add jsx factory and hold text in jsxtext node (#29439)

* add jsx factory and hold text in jsxtext node

* update jsxtext prop name and factory
This commit is contained in:
Wenlu Wang 2019-03-12 07:00:18 +08:00 committed by Wesley Wigham
parent 3ba5aa9f60
commit b97b1a8de6
10 changed files with 45 additions and 13 deletions

View File

@ -11576,7 +11576,7 @@ namespace ts {
// child is of the type of the expression
return { errorNode: child, innerExpression: child.expression, nameType };
case SyntaxKind.JsxText:
if (child.containsOnlyWhiteSpaces) {
if (child.containsOnlyTriviaWhiteSpaces) {
break; // Whitespace only jsx text isn't real jsx text
}
// child is a string
@ -11600,7 +11600,7 @@ namespace ts {
const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName);
const childrenNameType = getLiteralType(childrenPropName);
const childrenTargetType = getIndexedAccessType(target, childrenNameType);
const validChildren = filter(containingElement.children, i => !isJsxText(i) || !i.containsOnlyWhiteSpaces);
const validChildren = filter(containingElement.children, i => !isJsxText(i) || !i.containsOnlyTriviaWhiteSpaces);
if (!length(validChildren)) {
return result;
}
@ -18923,7 +18923,7 @@ namespace ts {
// In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
// because then type of children property will have constituent of string type.
if (child.kind === SyntaxKind.JsxText) {
if (!child.containsOnlyWhiteSpaces) {
if (!child.containsOnlyTriviaWhiteSpaces) {
childrenTypes.push(stringType);
}
}

View File

@ -2979,7 +2979,7 @@ namespace ts {
}
function emitJsxText(node: JsxText) {
writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true));
writer.writeLiteral(node.text);
}
function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) {

View File

@ -2299,6 +2299,28 @@ namespace ts {
return node;
}
export function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean) {
const node = <JsxText>createSynthesizedNode(SyntaxKind.JsxText);
node.text = text;
node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces;
return node;
}
export function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean) {
return node.text !== text
|| node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces
? updateNode(createJsxText(text, containsOnlyTriviaWhiteSpaces), node)
: node;
}
export function createJsxOpeningFragment() {
return <JsxOpeningFragment>createSynthesizedNode(SyntaxKind.JsxOpeningFragment);
}
export function createJsxJsxClosingFragment() {
return <JsxClosingFragment>createSynthesizedNode(SyntaxKind.JsxClosingFragment);
}
export function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment) {
return node.openingFragment !== openingFragment
|| node.children !== children

View File

@ -4256,7 +4256,8 @@ namespace ts {
function parseJsxText(): JsxText {
const node = <JsxText>createNode(SyntaxKind.JsxText);
node.containsOnlyWhiteSpaces = currentToken === SyntaxKind.JsxTextAllWhiteSpaces;
node.text = scanner.getTokenValue();
node.containsOnlyTriviaWhiteSpaces = currentToken === SyntaxKind.JsxTextAllWhiteSpaces;
currentToken = scanner.scanJsxToken();
return finishNode(node);
}

View File

@ -2013,6 +2013,7 @@ namespace ts {
pos++;
}
tokenValue = text.substring(startPos, pos);
return firstNonWhitespace === -1 ? SyntaxKind.JsxTextAllWhiteSpaces : SyntaxKind.JsxText;
}

View File

@ -182,7 +182,7 @@ namespace ts {
}
function visitJsxText(node: JsxText): StringLiteral | undefined {
const fixed = fixupWhitespaceAndDecodeEntities(getTextOfNode(node, /*includeTrivia*/ true));
const fixed = fixupWhitespaceAndDecodeEntities(node.text);
return fixed === undefined ? undefined : createLiteral(fixed);
}

View File

@ -1945,9 +1945,9 @@ namespace ts {
expression?: Expression;
}
export interface JsxText extends Node {
export interface JsxText extends LiteralLikeNode {
kind: SyntaxKind.JsxText;
containsOnlyWhiteSpaces: boolean;
containsOnlyTriviaWhiteSpaces: boolean;
parent: JsxElement;
}

View File

@ -905,7 +905,7 @@ namespace ts {
}
function isWhiteSpaceOnlyJsxText(node: Node): boolean {
return isJsxText(node) && node.containsOnlyWhiteSpaces;
return isJsxText(node) && node.containsOnlyTriviaWhiteSpaces;
}
export function isInTemplateString(sourceFile: SourceFile, position: number) {

View File

@ -1203,9 +1203,9 @@ declare namespace ts {
dotDotDotToken?: Token<SyntaxKind.DotDotDotToken>;
expression?: Expression;
}
interface JsxText extends Node {
interface JsxText extends LiteralLikeNode {
kind: SyntaxKind.JsxText;
containsOnlyWhiteSpaces: boolean;
containsOnlyTriviaWhiteSpaces: boolean;
parent: JsxElement;
}
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
@ -3992,6 +3992,10 @@ declare namespace ts {
function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement;
function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement;
function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText;
function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText;
function createJsxOpeningFragment(): JsxOpeningFragment;
function createJsxJsxClosingFragment(): JsxClosingFragment;
function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;

View File

@ -1203,9 +1203,9 @@ declare namespace ts {
dotDotDotToken?: Token<SyntaxKind.DotDotDotToken>;
expression?: Expression;
}
interface JsxText extends Node {
interface JsxText extends LiteralLikeNode {
kind: SyntaxKind.JsxText;
containsOnlyWhiteSpaces: boolean;
containsOnlyTriviaWhiteSpaces: boolean;
parent: JsxElement;
}
type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
@ -3992,6 +3992,10 @@ declare namespace ts {
function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement;
function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement;
function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function createJsxText(text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText;
function updateJsxText(node: JsxText, text: string, containsOnlyTriviaWhiteSpaces?: boolean): JsxText;
function createJsxOpeningFragment(): JsxOpeningFragment;
function createJsxJsxClosingFragment(): JsxClosingFragment;
function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment): JsxFragment;
function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;
function updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral | JsxExpression): JsxAttribute;