mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-20 19:45:07 -06:00
Fix jsx element parsing within ternary (#24149)
This commit is contained in:
parent
62921d56d6
commit
60df4671d0
@ -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) {
|
||||
|
||||
@ -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>);
|
||||
@ -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>
|
||||
);
|
||||
@ -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
|
||||
|
||||
);
|
||||
@ -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>
|
||||
);
|
||||
Loading…
x
Reference in New Issue
Block a user