Fix jsx element parsing within ternary (#24149)

This commit is contained in:
Wesley Wigham 2018-05-16 09:28:22 -07:00 committed by GitHub
parent 62921d56d6
commit 60df4671d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 7 deletions

View File

@ -2436,20 +2436,24 @@ namespace ts {
return finishNode(node);
}
/**
* @returns If return type parsing succeeds
*/
function fillSignature(
returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken,
flags: SignatureFlags,
signature: SignatureDeclaration): void {
signature: SignatureDeclaration): boolean {
if (!(flags & SignatureFlags.JSDoc)) {
signature.typeParameters = parseTypeParameters();
}
signature.parameters = parseParameterList(flags);
signature.type = parseReturnType(returnToken, !!(flags & SignatureFlags.Type));
if (shouldParseReturnType(returnToken, !!(flags & SignatureFlags.Type))) {
signature.type = parseTypeOrTypePredicate();
return signature.type !== undefined;
}
return true;
}
function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined {
return shouldParseReturnType(returnToken, isType) ? parseTypeOrTypePredicate() : undefined;
}
function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean {
if (returnToken === SyntaxKind.EqualsGreaterThanToken) {
parseExpected(returnToken);
@ -2758,6 +2762,9 @@ namespace ts {
const node = <ParenthesizedTypeNode>createNode(SyntaxKind.ParenthesizedType);
parseExpected(SyntaxKind.OpenParenToken);
node.type = parseType();
if (!node.type) {
return undefined;
}
parseExpected(SyntaxKind.CloseParenToken);
return finishNode(node);
}
@ -2767,7 +2774,12 @@ namespace ts {
if (kind === SyntaxKind.ConstructorType) {
parseExpected(SyntaxKind.NewKeyword);
}
fillSignature(SyntaxKind.EqualsGreaterThanToken, SignatureFlags.Type, node);
if (!fillSignature(SyntaxKind.EqualsGreaterThanToken, SignatureFlags.Type | (sourceFile.languageVariant === LanguageVariant.JSX ? SignatureFlags.RequireCompleteParameterList : 0), node)) {
return undefined;
}
if (!node.parameters) {
return undefined;
}
return finishNode(node);
}
@ -3598,7 +3610,9 @@ namespace ts {
// a => (b => c)
// And think that "(b =>" was actually a parenthesized arrow function with a missing
// close paren.
fillSignature(SyntaxKind.ColonToken, isAsync | (allowAmbiguity ? SignatureFlags.None : SignatureFlags.RequireCompleteParameterList), node);
if (!fillSignature(SyntaxKind.ColonToken, isAsync | (allowAmbiguity ? SignatureFlags.None : SignatureFlags.RequireCompleteParameterList), node)) {
return undefined;
}
// If we couldn't get parameters, we definitely could not parse out an arrow function.
if (!node.parameters) {

View File

@ -0,0 +1,25 @@
//// [jsxNestedWithinTernaryParsesCorrectly.tsx]
const emptyMessage = null as any;
const a = (
<div>
{0 ? (
emptyMessage // must be identifier?
) : (
// must be exactly two expression holes
<span>
{0}{0}
</span>
)}
</div>
);
//// [jsxNestedWithinTernaryParsesCorrectly.jsx]
var emptyMessage = null;
var a = (<div>
{0 ? (emptyMessage // must be identifier?
) : (
// must be exactly two expression holes
<span>
{0}{0}
</span>)}
</div>);

View File

@ -0,0 +1,20 @@
=== tests/cases/compiler/jsxNestedWithinTernaryParsesCorrectly.tsx ===
const emptyMessage = null as any;
>emptyMessage : Symbol(emptyMessage, Decl(jsxNestedWithinTernaryParsesCorrectly.tsx, 0, 5))
const a = (
>a : Symbol(a, Decl(jsxNestedWithinTernaryParsesCorrectly.tsx, 1, 5))
<div>
{0 ? (
emptyMessage // must be identifier?
>emptyMessage : Symbol(emptyMessage, Decl(jsxNestedWithinTernaryParsesCorrectly.tsx, 0, 5))
) : (
// must be exactly two expression holes
<span>
{0}{0}
</span>
)}
</div>
);

View File

@ -0,0 +1,42 @@
=== tests/cases/compiler/jsxNestedWithinTernaryParsesCorrectly.tsx ===
const emptyMessage = null as any;
>emptyMessage : any
>null as any : any
>null : null
const a = (
>a : any
>( <div> {0 ? ( emptyMessage // must be identifier? ) : ( // must be exactly two expression holes <span> {0}{0} </span> )} </div>) : any
<div>
><div> {0 ? ( emptyMessage // must be identifier? ) : ( // must be exactly two expression holes <span> {0}{0} </span> )} </div> : any
>div : any
{0 ? (
>0 ? ( emptyMessage // must be identifier? ) : ( // must be exactly two expression holes <span> {0}{0} </span> ) : any
>0 : 0
>( emptyMessage // must be identifier? ) : any
emptyMessage // must be identifier?
>emptyMessage : any
) : (
>( // must be exactly two expression holes <span> {0}{0} </span> ) : any
// must be exactly two expression holes
<span>
><span> {0}{0} </span> : any
>span : any
{0}{0}
>0 : 0
>0 : 0
</span>
>span : any
)}
</div>
>div : any
);

View File

@ -0,0 +1,14 @@
// @jsx: preserve
const emptyMessage = null as any;
const a = (
<div>
{0 ? (
emptyMessage // must be identifier?
) : (
// must be exactly two expression holes
<span>
{0}{0}
</span>
)}
</div>
);