From 0e4fdf8373de39200ddc41ca6fea68fe2875a66e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 26 Aug 2015 16:12:50 -0700 Subject: [PATCH] Use synthetic identifier during emit instead --- src/compiler/checker.ts | 6 +-- src/compiler/emitter.ts | 18 +++----- tests/baselines/reference/tsxReactEmit6.js | 36 ++++++++++++++++ .../baselines/reference/tsxReactEmit6.symbols | 39 ++++++++++++++++++ tests/baselines/reference/tsxReactEmit6.types | 41 +++++++++++++++++++ tests/cases/conformance/jsx/tsxReactEmit6.tsx | 22 ++++++++++ 6 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 tests/baselines/reference/tsxReactEmit6.js create mode 100644 tests/baselines/reference/tsxReactEmit6.symbols create mode 100644 tests/baselines/reference/tsxReactEmit6.types create mode 100644 tests/cases/conformance/jsx/tsxReactEmit6.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 48697bc548e..cff964361a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7629,12 +7629,8 @@ namespace ts { // is no 'React' symbol in scope, we should issue an error. if (compilerOptions.jsx === JsxEmit.React) { let reactSym = resolveName(node.tagName, "React", SymbolFlags.Value, Diagnostics.Cannot_find_name_0, "React"); - if (reactSym && reactSym !== unknownSymbol) { + if (reactSym) { getSymbolLinks(reactSym).referenced = true; - let reactNode = createSynthesizedNode(SyntaxKind.Identifier, false); - reactNode.text = 'React'; - getNodeLinks(reactNode).resolvedSymbol = reactSym; - node.reactNode = reactNode; } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8525e2addee..eeaab6d2123 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1177,14 +1177,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } function emitJsxElement(openingNode: JsxOpeningLikeElement, children?: JsxChild[]) { + let syntheticReactRef = createSynthesizedNode(SyntaxKind.Identifier); + syntheticReactRef.text = 'React'; + syntheticReactRef.parent = openingNode; + // Call React.createElement(tag, ... emitLeadingComments(openingNode); - if (openingNode.reactNode) { - emitExpressionIdentifier(openingNode.reactNode); - } - else { - write('React'); - } + emitExpressionIdentifier(syntheticReactRef); write(".createElement("); emitTagName(openingNode.tagName); write(", "); @@ -1199,12 +1198,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // a call to React.__spread let attrs = openingNode.attributes; if (forEach(attrs, attr => attr.kind === SyntaxKind.JsxSpreadAttribute)) { - if (openingNode.reactNode) { - emitExpressionIdentifier(openingNode.reactNode); - } - else { - write('React'); - } + emitExpressionIdentifier(syntheticReactRef); write(".__spread("); let haveOpenedObjectLiteral = false; diff --git a/tests/baselines/reference/tsxReactEmit6.js b/tests/baselines/reference/tsxReactEmit6.js new file mode 100644 index 00000000000..d20ef7051e0 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit6.js @@ -0,0 +1,36 @@ +//// [tests/cases/conformance/jsx/tsxReactEmit6.tsx] //// + +//// [file.tsx] + +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +//// [react-consumer.tsx] +namespace M { + export var React: any; +} + +namespace M { + // Should emit M.React.createElement + // and M.React.__spread + var foo; + var spread1 =
; +} + + +//// [file.js] +//// [react-consumer.js] +var M; +(function (M) { +})(M || (M = {})); +var M; +(function (M) { + // Should emit M.React.createElement + // and M.React.__spread + var foo; + var spread1 = M.React.createElement("div", M.React.__spread({x: ''}, foo, {y: ''})); +})(M || (M = {})); diff --git a/tests/baselines/reference/tsxReactEmit6.symbols b/tests/baselines/reference/tsxReactEmit6.symbols new file mode 100644 index 00000000000..0302cef3e8d --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit6.symbols @@ -0,0 +1,39 @@ +=== tests/cases/conformance/jsx/file.tsx === + +declare module JSX { +>JSX : Symbol(JSX, Decl(file.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(file.tsx, 1, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 2, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(file.tsx, 4, 3)) + } +} + +=== tests/cases/conformance/jsx/react-consumer.tsx === +namespace M { +>M : Symbol(M, Decl(react-consumer.tsx, 0, 0), Decl(react-consumer.tsx, 2, 1)) + + export var React: any; +>React : Symbol(React, Decl(react-consumer.tsx, 1, 11)) +} + +namespace M { +>M : Symbol(M, Decl(react-consumer.tsx, 0, 0), Decl(react-consumer.tsx, 2, 1)) + + // Should emit M.React.createElement + // and M.React.__spread + var foo; +>foo : Symbol(foo, Decl(react-consumer.tsx, 7, 4)) + + var spread1 =
; +>spread1 : Symbol(spread1, Decl(react-consumer.tsx, 8, 4)) +>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 2, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) +} + diff --git a/tests/baselines/reference/tsxReactEmit6.types b/tests/baselines/reference/tsxReactEmit6.types new file mode 100644 index 00000000000..1b16b84fcc7 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit6.types @@ -0,0 +1,41 @@ +=== tests/cases/conformance/jsx/file.tsx === + +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +=== tests/cases/conformance/jsx/react-consumer.tsx === +namespace M { +>M : typeof M + + export var React: any; +>React : any +} + +namespace M { +>M : typeof M + + // Should emit M.React.createElement + // and M.React.__spread + var foo; +>foo : any + + var spread1 =
; +>spread1 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>foo : any +>y : any +} + diff --git a/tests/cases/conformance/jsx/tsxReactEmit6.tsx b/tests/cases/conformance/jsx/tsxReactEmit6.tsx new file mode 100644 index 00000000000..2782f90e503 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmit6.tsx @@ -0,0 +1,22 @@ +//@jsx: react +//@module: commonjs + +//@filename: file.tsx +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +//@filename: react-consumer.tsx +namespace M { + export var React: any; +} + +namespace M { + // Should emit M.React.createElement + // and M.React.__spread + var foo; + var spread1 =
; +}