mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 11:35:42 -06:00
Additional fixes for React emit.
This commit is contained in:
parent
221cbcfe29
commit
0b2264cc54
@ -66,7 +66,7 @@ namespace ts {
|
||||
// We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
|
||||
// the original node. We also need to exclude specific properties and only include own-
|
||||
// properties (to skip members already defined on the shared prototype).
|
||||
const clone = <T>createSynthesizedNode(node.kind);
|
||||
const clone = <T>createNode(node.kind, /*location*/ undefined);
|
||||
clone.flags = node.flags;
|
||||
clone.original = node;
|
||||
|
||||
@ -784,17 +784,25 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createJsxSpread(reactNamespace: string, segments: Expression[]) {
|
||||
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) {
|
||||
// Create an identifier and give it a parent. This allows us to resolve the react
|
||||
// namespace during emit.
|
||||
const react = createIdentifier(reactNamespace || "React");
|
||||
react.parent = parent;
|
||||
return react;
|
||||
}
|
||||
|
||||
export function createReactSpread(reactNamespace: string, segments: Expression[], parentElement: JsxOpeningLikeElement) {
|
||||
return createCall(
|
||||
createPropertyAccess(
|
||||
createIdentifier(reactNamespace || "React"),
|
||||
createReactNamespace(reactNamespace, parentElement),
|
||||
"__spread"
|
||||
),
|
||||
segments
|
||||
);
|
||||
}
|
||||
|
||||
export function createJsxCreateElement(reactNamespace: string, tagName: Expression, props: Expression, children: Expression[]): LeftHandSideExpression {
|
||||
export function createReactCreateElement(reactNamespace: string, tagName: Expression, props: Expression, children: Expression[], parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
|
||||
const argumentsList = [tagName];
|
||||
if (props) {
|
||||
argumentsList.push(props);
|
||||
@ -805,15 +813,16 @@ namespace ts {
|
||||
argumentsList.push(createNull());
|
||||
}
|
||||
|
||||
addRange(argumentsList, children);
|
||||
addNodes(argumentsList, children, /*startOnNewLine*/ children.length > 1);
|
||||
}
|
||||
|
||||
return createCall(
|
||||
createPropertyAccess(
|
||||
createIdentifier(reactNamespace || "React"),
|
||||
createReactNamespace(reactNamespace, parentElement),
|
||||
"createElement"
|
||||
),
|
||||
argumentsList
|
||||
argumentsList,
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1017,9 +1017,7 @@ const _super = (function (geti, seti) {
|
||||
function emitNewExpression(node: NewExpression) {
|
||||
write("new ");
|
||||
emitExpression(node.expression);
|
||||
if (node.arguments) {
|
||||
emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments);
|
||||
}
|
||||
emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments);
|
||||
}
|
||||
|
||||
function emitTaggedTemplateExpression(node: TaggedTemplateExpression) {
|
||||
@ -1536,7 +1534,7 @@ const _super = (function (geti, seti) {
|
||||
write("interface ");
|
||||
emit(node.name);
|
||||
emitTypeParameters(node, node.typeParameters);
|
||||
emitList(node, node.heritageClauses, ListFormat.SingleLine);
|
||||
emitList(node, node.heritageClauses, ListFormat.HeritageClauses);
|
||||
write(" {");
|
||||
emitList(node, node.members, ListFormat.InterfaceMembers);
|
||||
write("}");
|
||||
@ -1722,7 +1720,7 @@ const _super = (function (geti, seti) {
|
||||
|
||||
function emitJsxSelfClosingElement(node: JsxSelfClosingElement) {
|
||||
write("<");
|
||||
emit(node.tagName);
|
||||
emitJsxTagName(node.tagName);
|
||||
write(" ");
|
||||
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
|
||||
write("/>");
|
||||
@ -1730,7 +1728,7 @@ const _super = (function (geti, seti) {
|
||||
|
||||
function emitJsxOpeningElement(node: JsxOpeningElement) {
|
||||
write("<");
|
||||
emit(node.tagName);
|
||||
emitJsxTagName(node.tagName);
|
||||
writeIfAny(node.attributes, " ");
|
||||
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
|
||||
write(">");
|
||||
@ -1742,7 +1740,7 @@ const _super = (function (geti, seti) {
|
||||
|
||||
function emitJsxClosingElement(node: JsxClosingElement) {
|
||||
write("</");
|
||||
emit(node.tagName);
|
||||
emitJsxTagName(node.tagName);
|
||||
write(">");
|
||||
}
|
||||
|
||||
@ -1758,9 +1756,20 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function emitJsxExpression(node: JsxExpression) {
|
||||
write("{");
|
||||
emitExpression(node.expression);
|
||||
write("}");
|
||||
if (node.expression) {
|
||||
write("{");
|
||||
emitExpression(node.expression);
|
||||
write("}");
|
||||
}
|
||||
}
|
||||
|
||||
function emitJsxTagName(node: EntityName) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
emitExpression(<Identifier>node);
|
||||
}
|
||||
else {
|
||||
emit(node);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@ -2168,6 +2177,7 @@ const _super = (function (geti, seti) {
|
||||
|
||||
// Emit each child.
|
||||
let previousSibling: Node;
|
||||
let shouldDecreaseIndentAfterEmit: boolean;
|
||||
const delimiter = getDelimiter(format);
|
||||
for (let i = 0; i < count; i++) {
|
||||
const child = children[start + i];
|
||||
@ -2178,6 +2188,13 @@ const _super = (function (geti, seti) {
|
||||
|
||||
// Write either a line terminator or whitespace to separate the elements.
|
||||
if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) {
|
||||
// If a synthesized node in a single-line list starts on a new
|
||||
// line, we should increase the indent.
|
||||
if ((format & (ListFormat.LinesMask | ListFormat.Indented)) === ListFormat.SingleLine) {
|
||||
increaseIndent();
|
||||
shouldDecreaseIndentAfterEmit = true;
|
||||
}
|
||||
|
||||
writeLine();
|
||||
shouldEmitInterveningComments = false;
|
||||
}
|
||||
@ -2196,6 +2213,11 @@ const _super = (function (geti, seti) {
|
||||
// Emit this child.
|
||||
emit(child);
|
||||
|
||||
if (shouldDecreaseIndentAfterEmit) {
|
||||
decreaseIndent();
|
||||
shouldDecreaseIndentAfterEmit = false;
|
||||
}
|
||||
|
||||
previousSibling = child;
|
||||
}
|
||||
|
||||
@ -2322,7 +2344,7 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
return nextNode.startsOnNewLine;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2619,40 +2641,43 @@ const _super = (function (geti, seti) {
|
||||
None = 0,
|
||||
|
||||
// Line separators
|
||||
SingleLine = 1 << 0, // Prints the list on a single line (default).
|
||||
MultiLine = 1 << 1, // Prints the list on multiple lines.
|
||||
PreserveLines = 1 << 2, // Prints the list using line preservation if possible.
|
||||
SingleLine = 0, // Prints the list on a single line (default).
|
||||
MultiLine = 1 << 0, // Prints the list on multiple lines.
|
||||
PreserveLines = 1 << 1, // Prints the list using line preservation if possible.
|
||||
LinesMask = SingleLine | MultiLine | PreserveLines,
|
||||
|
||||
// Delimiters
|
||||
NotDelimited = 0, // There is no delimiter between list items (default).
|
||||
BarDelimited = 1 << 3, // Each list item is space-and-bar (" |") delimited.
|
||||
AmpersandDelimited = 1 << 4, // Each list item is space-and-ampersand (" &") delimited.
|
||||
CommaDelimited = 1 << 5, // Each list item is comma (",") delimited.
|
||||
AllowTrailingComma = 1 << 6, // Write a trailing comma (",") if present.
|
||||
BarDelimited = 1 << 2, // Each list item is space-and-bar (" |") delimited.
|
||||
AmpersandDelimited = 1 << 3, // Each list item is space-and-ampersand (" &") delimited.
|
||||
CommaDelimited = 1 << 4, // Each list item is comma (",") delimited.
|
||||
DelimitersMask = BarDelimited | AmpersandDelimited | CommaDelimited,
|
||||
|
||||
AllowTrailingComma = 1 << 5, // Write a trailing comma (",") if present.
|
||||
|
||||
// Whitespace
|
||||
Indented = 1 << 7, // The list should be indented.
|
||||
SpaceBetweenBraces = 1 << 8, // Inserts a space after the opening brace and before the closing brace.
|
||||
SpaceBetweenSiblings = 1 << 9, // Inserts a space between each sibling node.
|
||||
Indented = 1 << 6, // The list should be indented.
|
||||
SpaceBetweenBraces = 1 << 7, // Inserts a space after the opening brace and before the closing brace.
|
||||
SpaceBetweenSiblings = 1 << 8, // Inserts a space between each sibling node.
|
||||
|
||||
// Brackets/Braces
|
||||
Braces = 1 << 10, // The list is surrounded by "{" and "}".
|
||||
Parenthesis = 1 << 11, // The list is surrounded by "(" and ")".
|
||||
AngleBrackets = 1 << 12, // The list is surrounded by "<" and ">".
|
||||
SquareBrackets = 1 << 13, // The list is surrounded by "[" and "]".
|
||||
OptionalIfUndefined = 1 << 14, // Do not emit brackets if the list is undefined.
|
||||
OptionalIfEmpty = 1 << 15, // Do not emit brackets if the list is empty.
|
||||
Optional = OptionalIfUndefined | OptionalIfEmpty,
|
||||
Braces = 1 << 9, // The list is surrounded by "{" and "}".
|
||||
Parenthesis = 1 << 10, // The list is surrounded by "(" and ")".
|
||||
AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">".
|
||||
SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]".
|
||||
BracketsMask = Braces | Parenthesis | AngleBrackets | SquareBrackets,
|
||||
|
||||
OptionalIfUndefined = 1 << 13, // Do not emit brackets if the list is undefined.
|
||||
OptionalIfEmpty = 1 << 14, // Do not emit brackets if the list is empty.
|
||||
Optional = OptionalIfUndefined | OptionalIfEmpty,
|
||||
|
||||
// Other
|
||||
PreferNewLine = 1 << 16, // Prefer adding a LineTerminator between synthesized nodes.
|
||||
NoTrailingNewLine = 1 << 17, // Do not emit a trailing NewLine for a MultiLine list.
|
||||
PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes.
|
||||
NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list.
|
||||
|
||||
// Precomputed Formats
|
||||
Modifiers = SingleLine | SpaceBetweenSiblings,
|
||||
HeritageClauses = SingleLine | SpaceBetweenSiblings,
|
||||
TypeLiteralMembers = MultiLine | Indented,
|
||||
TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented,
|
||||
UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
|
||||
@ -33,10 +33,10 @@ namespace ts {
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxElement:
|
||||
return visitJsxElement(<JsxElement>node);
|
||||
return visitJsxElement(<JsxElement>node, /*isChild*/ false);
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ false);
|
||||
|
||||
case SyntaxKind.JsxExpression:
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
@ -56,10 +56,10 @@ namespace ts {
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
|
||||
case SyntaxKind.JsxElement:
|
||||
return visitJsxElement(<JsxElement>node);
|
||||
return visitJsxElement(<JsxElement>node, /*isChild*/ true);
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ true);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
@ -67,15 +67,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitJsxElement(node: JsxElement) {
|
||||
return visitJsxOpeningLikeElement(node.openingElement, node.children);
|
||||
function visitJsxElement(node: JsxElement, isChild: boolean) {
|
||||
return visitJsxOpeningLikeElement(node.openingElement, node.children, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxSelfClosingElement(node: JsxSelfClosingElement) {
|
||||
return visitJsxOpeningLikeElement(node, /*children*/ undefined);
|
||||
function visitJsxSelfClosingElement(node: JsxSelfClosingElement, isChild: boolean) {
|
||||
return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[]) {
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
const attrs = node.attributes;
|
||||
@ -102,15 +102,23 @@ namespace ts {
|
||||
// Either emit one big object literal (no spread attribs), or
|
||||
// a call to React.__spread
|
||||
objectProperties = singleOrUndefined(segments)
|
||||
|| createJsxSpread(compilerOptions.reactNamespace, segments);
|
||||
|| createReactSpread(compilerOptions.reactNamespace, segments, node);
|
||||
}
|
||||
|
||||
return createJsxCreateElement(
|
||||
const element = createReactCreateElement(
|
||||
compilerOptions.reactNamespace,
|
||||
tagName,
|
||||
objectProperties,
|
||||
filter(map(children, transformJsxChildToExpression), isDefined)
|
||||
filter(map(children, transformJsxChildToExpression), isDefined),
|
||||
node,
|
||||
location
|
||||
);
|
||||
|
||||
if (isChild) {
|
||||
startOnNewLine(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) {
|
||||
|
||||
@ -148,7 +148,10 @@ var x = <div attr1={"foo" + "bar"} attr2={"foo" + "bar" +
|
||||
|
||||
|
||||
</div>);
|
||||
(<div attr1="foo">
|
||||
(<div
|
||||
/* a multi-line
|
||||
comment */
|
||||
attr1="foo">
|
||||
<span // a double-slash comment
|
||||
attr2="bar"/>
|
||||
</div>);
|
||||
|
||||
@ -8,7 +8,7 @@ declare var React: any;
|
||||
|
||||
|
||||
//// [keywordInJsxIdentifier.js]
|
||||
React.createElement("foo", {"class-id": true});
|
||||
React.createElement("foo", {class: true});
|
||||
React.createElement("foo", {"class-id": "1"});
|
||||
React.createElement("foo", {class: "1"});
|
||||
React.createElement("foo", { "class-id": true });
|
||||
React.createElement("foo", { class: true });
|
||||
React.createElement("foo", { "class-id": "1" });
|
||||
React.createElement("foo", { class: "1" });
|
||||
|
||||
@ -4,4 +4,4 @@
|
||||
|
||||
|
||||
//// [reactNamespaceInvalidInput.js]
|
||||
my-React-Lib.createElement("foo", {data: true});
|
||||
my-React-Lib.createElement("foo", { data: true });
|
||||
|
||||
@ -13,8 +13,8 @@ declare var x: any;
|
||||
|
||||
|
||||
//// [reactNamespaceJSXEmit.js]
|
||||
myReactLib.createElement("foo", {data: true});
|
||||
myReactLib.createElement(Bar, {x: x});
|
||||
myReactLib.createElement("foo", { data: true });
|
||||
myReactLib.createElement(Bar, { x: x });
|
||||
myReactLib.createElement("x-component", null);
|
||||
myReactLib.createElement(Bar, myReactLib.__spread({}, x));
|
||||
myReactLib.createElement(Bar, myReactLib.__spread({}, x, {y: 2}));
|
||||
myReactLib.createElement(Bar, myReactLib.__spread({}, x, { y: 2 }));
|
||||
|
||||
@ -5,4 +5,4 @@
|
||||
|
||||
//// [reactNamespaceMissingDeclaration.js]
|
||||
// Error myReactLib not declared
|
||||
myReactLib.createElement("foo", {data: true});
|
||||
myReactLib.createElement("foo", { data: true });
|
||||
|
||||
@ -12,6 +12,8 @@ var x = <div></div><div></div>
|
||||
|
||||
|
||||
//// [file1.js]
|
||||
React.createElement("div", null), React.createElement("div", null);
|
||||
React.createElement("div", null)
|
||||
,
|
||||
React.createElement("div", null);
|
||||
//// [file2.js]
|
||||
var x = (React.createElement("div", null), React.createElement("div", null));
|
||||
|
||||
@ -70,5 +70,8 @@ var SomeClass = (function () {
|
||||
return SomeClass;
|
||||
}());
|
||||
var whitespace1 = React.createElement("div", null, " ");
|
||||
var whitespace2 = React.createElement("div", null, " ", p, " ");
|
||||
var whitespace2 = React.createElement("div", null,
|
||||
" ",
|
||||
p,
|
||||
" ");
|
||||
var whitespace3 = React.createElement("div", null, p);
|
||||
|
||||
@ -8,4 +8,11 @@ declare var Foo, Bar, baz;
|
||||
<Foo> <Bar> q </Bar> <Bar/> s <Bar/><Bar/></Foo>;
|
||||
|
||||
//// [test.js]
|
||||
React.createElement(Foo, null, " ", React.createElement(Bar, null, " q "), " ", React.createElement(Bar, null), " s ", React.createElement(Bar, null), React.createElement(Bar, null));
|
||||
React.createElement(Foo, null,
|
||||
" ",
|
||||
React.createElement(Bar, null, " q "),
|
||||
" ",
|
||||
React.createElement(Bar, null),
|
||||
" s ",
|
||||
React.createElement(Bar, null),
|
||||
React.createElement(Bar, null));
|
||||
|
||||
@ -27,4 +27,4 @@ var test_1 = require("./test");
|
||||
// Should emit test_1.React.createElement
|
||||
// and React.__spread
|
||||
var foo;
|
||||
var spread1 = test_1.React.createElement("div", test_1.React.__spread({x: ''}, foo, {y: ''}));
|
||||
var spread1 = test_1.React.createElement("div", test_1.React.__spread({ x: '' }, foo, { y: '' }));
|
||||
|
||||
@ -36,7 +36,7 @@ var M;
|
||||
// Should emit M.React.createElement
|
||||
// and M.React.__spread
|
||||
var foo;
|
||||
var spread1 = M.React.createElement("div", M.React.__spread({x: ''}, foo, {y: ''}));
|
||||
var spread1 = M.React.createElement("div", M.React.__spread({ x: '' }, foo, { y: '' }));
|
||||
// Quotes
|
||||
var x = M.React.createElement("div", null, "This \"quote\" thing");
|
||||
})(M || (M = {}));
|
||||
|
||||
@ -12,5 +12,5 @@ declare var React: any;
|
||||
|
||||
|
||||
//// [file.js]
|
||||
React.createElement("div", null, "Dot goes here: · ¬AnEntity; ");
|
||||
React.createElement("div", null, "Dot goes here: \u00B7 ¬AnEntity; ");
|
||||
React.createElement("div", null, "Be careful of \"-ed strings!");
|
||||
|
||||
@ -38,23 +38,21 @@ let render = (ctrl, model) =>
|
||||
//// [file.js]
|
||||
// A simple render function with nesting and control statements
|
||||
var render = function (ctrl, model) {
|
||||
return vdom.createElement("section", {class: "todoapp"},
|
||||
vdom.createElement("header", {class: "header"},
|
||||
vdom.createElement("h1", null, "todos <x>"),
|
||||
vdom.createElement("input", {class: "new-todo", autofocus: true, autocomplete: "off", placeholder: "What needs to be done?", value: model.newTodo, onKeyup: ctrl.addTodo.bind(ctrl, model)})),
|
||||
vdom.createElement("section", {class: "main", style: { display: (model.todos && model.todos.length) ? "block" : "none" }},
|
||||
vdom.createElement("input", {class: "toggle-all", type: "checkbox", onChange: ctrl.toggleAll.bind(ctrl)}),
|
||||
vdom.createElement("ul", {class: "todo-list"}, model.filteredTodos.map(function (todo) {
|
||||
return vdom.createElement("li", {class: { todo: true, completed: todo.completed, editing: todo == model.editedTodo }},
|
||||
vdom.createElement("div", {class: "view"},
|
||||
return vdom.createElement("section", { class: "todoapp" },
|
||||
vdom.createElement("header", { class: "header" },
|
||||
vdom.createElement("h1", null, "todos <x>"),
|
||||
vdom.createElement("input", { class: "new-todo", autofocus: true, autocomplete: "off", placeholder: "What needs to be done?", value: model.newTodo, onKeyup: ctrl.addTodo.bind(ctrl, model) })),
|
||||
vdom.createElement("section", { class: "main", style: { display: (model.todos && model.todos.length) ? "block" : "none" } },
|
||||
vdom.createElement("input", { class: "toggle-all", type: "checkbox", onChange: ctrl.toggleAll.bind(ctrl) }),
|
||||
vdom.createElement("ul", { class: "todo-list" }, model.filteredTodos.map(function (todo) {
|
||||
return vdom.createElement("li", { class: { todo: true, completed: todo.completed, editing: todo == model.editedTodo } },
|
||||
vdom.createElement("div", { class: "view" },
|
||||
(!todo.editable) ?
|
||||
vdom.createElement("input", {class: "toggle", type: "checkbox"})
|
||||
: null,
|
||||
vdom.createElement("label", {onDoubleClick: function () { ctrl.editTodo(todo); }}, todo.title),
|
||||
vdom.createElement("button", {class: "destroy", onClick: ctrl.removeTodo.bind(ctrl, todo)}),
|
||||
vdom.createElement("div", {class: "iconBorder"},
|
||||
vdom.createElement("div", {class: "icon"})
|
||||
))
|
||||
);
|
||||
vdom.createElement("input", { class: "toggle", type: "checkbox" })
|
||||
: null,
|
||||
vdom.createElement("label", { onDoubleClick: function () { ctrl.editTodo(todo); } }, todo.title),
|
||||
vdom.createElement("button", { class: "destroy", onClick: ctrl.removeTodo.bind(ctrl, todo) }),
|
||||
vdom.createElement("div", { class: "iconBorder" },
|
||||
vdom.createElement("div", { class: "icon" }))));
|
||||
}))));
|
||||
};
|
||||
|
||||
@ -59,9 +59,9 @@ var p = 0;
|
||||
// Emit " "
|
||||
React.createElement("div", null, " ");
|
||||
// Emit " ", p, " "
|
||||
React.createElement("div", null,
|
||||
" ",
|
||||
p,
|
||||
React.createElement("div", null,
|
||||
" ",
|
||||
p,
|
||||
" ");
|
||||
// Emit only p
|
||||
React.createElement("div", null, p);
|
||||
@ -76,4 +76,4 @@ React.createElement("div", null, "3");
|
||||
// Emit no args
|
||||
React.createElement("div", null);
|
||||
// Emit "foo" + ' ' + "bar"
|
||||
React.createElement("div", null, "foo" + ' ' + "bar");
|
||||
React.createElement("div", null, "foo" + " " + "bar");
|
||||
|
||||
@ -18,15 +18,15 @@ declare var React: any;
|
||||
|
||||
//// [file.js]
|
||||
// Emit ' word' in the last string
|
||||
React.createElement("div", null,
|
||||
"word ",
|
||||
React.createElement("code", null, "code"),
|
||||
React.createElement("div", null,
|
||||
"word ",
|
||||
React.createElement("code", null, "code"),
|
||||
" word");
|
||||
// Same here
|
||||
React.createElement("div", null,
|
||||
React.createElement("code", null, "code"),
|
||||
React.createElement("div", null,
|
||||
React.createElement("code", null, "code"),
|
||||
" word");
|
||||
// And here
|
||||
React.createElement("div", null,
|
||||
React.createElement("code", null),
|
||||
React.createElement("div", null,
|
||||
React.createElement("code", null),
|
||||
" word");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user