Do not transform JSX tag names for ES3

This commit is contained in:
Ron Buckton 2016-12-15 16:33:49 -08:00
parent cb6bf11e71
commit 40d08df90b
5 changed files with 192 additions and 0 deletions

View file

@ -9,6 +9,20 @@ namespace ts {
* @param context Context and state information for the transformation.
*/
export function transformES5(context: TransformationContext) {
const compilerOptions = context.getCompilerOptions();
// enable emit notification only if using --jsx preserve
let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
let noSubstitution: boolean[];
if (compilerOptions.jsx === JsxEmit.Preserve) {
previousOnEmitNode = context.onEmitNode;
context.onEmitNode = onEmitNode;
context.enableEmitNotification(SyntaxKind.JsxOpeningElement);
context.enableEmitNotification(SyntaxKind.JsxClosingElement);
context.enableEmitNotification(SyntaxKind.JsxSelfClosingElement);
noSubstitution = [];
}
const previousOnSubstituteNode = context.onSubstituteNode;
context.onSubstituteNode = onSubstituteNode;
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
@ -24,6 +38,24 @@ namespace ts {
return node;
}
/**
* Called by the printer just before a node is printed.
*
* @param node The node to be printed.
*/
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
switch (node.kind) {
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxClosingElement:
case SyntaxKind.JsxSelfClosingElement:
const tagName = (<JsxOpeningElement | JsxClosingElement | JsxSelfClosingElement>node).tagName;
noSubstitution[getOriginalNodeId(tagName)] = true;
break;
}
previousOnEmitNode(emitContext, node, emitCallback);
}
/**
* Hooks node substitutions.
*
@ -31,6 +63,10 @@ namespace ts {
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
if (node.id && noSubstitution[node.id]) {
return previousOnSubstituteNode(emitContext, node);
}
node = previousOnSubstituteNode(emitContext, node);
if (isPropertyAccessExpression(node)) {
return substitutePropertyAccessExpression(node);

View file

@ -0,0 +1,44 @@
//// [tests/cases/compiler/jsxViaImport.2.tsx] ////
//// [component.d.ts]
declare module JSX {
interface ElementAttributesProperty { props; }
}
declare module React {
class Component<T, U> { }
}
declare module "BaseComponent" {
export default class extends React.Component<any, {}> {
}
}
//// [consumer.tsx]
/// <reference path="component.d.ts" />
import BaseComponent from 'BaseComponent';
class TestComponent extends React.Component<any, {}> {
render() {
return <BaseComponent />;
}
}
//// [consumer.jsx]
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/// <reference path="component.d.ts" />
var BaseComponent_1 = require("BaseComponent");
var TestComponent = (function (_super) {
__extends(TestComponent, _super);
function TestComponent() {
return _super.apply(this, arguments) || this;
}
TestComponent.prototype.render = function () {
return <BaseComponent_1.default />;
};
return TestComponent;
}(React.Component));

View file

@ -0,0 +1,44 @@
=== tests/cases/compiler/consumer.tsx ===
/// <reference path="component.d.ts" />
import BaseComponent from 'BaseComponent';
>BaseComponent : Symbol(BaseComponent, Decl(consumer.tsx, 1, 6))
class TestComponent extends React.Component<any, {}> {
>TestComponent : Symbol(TestComponent, Decl(consumer.tsx, 1, 42))
>React.Component : Symbol(React.Component, Decl(component.d.ts, 4, 22))
>React : Symbol(React, Decl(component.d.ts, 3, 1))
>Component : Symbol(React.Component, Decl(component.d.ts, 4, 22))
render() {
>render : Symbol(TestComponent.render, Decl(consumer.tsx, 2, 54))
return <BaseComponent />;
>BaseComponent : Symbol(BaseComponent, Decl(consumer.tsx, 1, 6))
}
}
=== tests/cases/compiler/component.d.ts ===
declare module JSX {
>JSX : Symbol(JSX, Decl(component.d.ts, 0, 0))
interface ElementAttributesProperty { props; }
>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(component.d.ts, 1, 20))
>props : Symbol(ElementAttributesProperty.props, Decl(component.d.ts, 2, 39))
}
declare module React {
>React : Symbol(React, Decl(component.d.ts, 3, 1))
class Component<T, U> { }
>Component : Symbol(Component, Decl(component.d.ts, 4, 22))
>T : Symbol(T, Decl(component.d.ts, 5, 18))
>U : Symbol(U, Decl(component.d.ts, 5, 20))
}
declare module "BaseComponent" {
export default class extends React.Component<any, {}> {
>React.Component : Symbol(React.Component, Decl(component.d.ts, 4, 22))
>React : Symbol(React, Decl(component.d.ts, 3, 1))
>Component : Symbol(React.Component, Decl(component.d.ts, 4, 22))
}
}

View file

@ -0,0 +1,45 @@
=== tests/cases/compiler/consumer.tsx ===
/// <reference path="component.d.ts" />
import BaseComponent from 'BaseComponent';
>BaseComponent : typeof BaseComponent
class TestComponent extends React.Component<any, {}> {
>TestComponent : TestComponent
>React.Component : React.Component<any, {}>
>React : typeof React
>Component : typeof React.Component
render() {
>render : () => any
return <BaseComponent />;
><BaseComponent /> : any
>BaseComponent : typeof BaseComponent
}
}
=== tests/cases/compiler/component.d.ts ===
declare module JSX {
>JSX : any
interface ElementAttributesProperty { props; }
>ElementAttributesProperty : ElementAttributesProperty
>props : any
}
declare module React {
>React : typeof React
class Component<T, U> { }
>Component : Component<T, U>
>T : T
>U : U
}
declare module "BaseComponent" {
export default class extends React.Component<any, {}> {
>React.Component : React.Component<any, {}>
>React : typeof React
>Component : typeof React.Component
}
}

View file

@ -0,0 +1,23 @@
//@jsx: preserve
//@module: commonjs
//@filename: component.d.ts
declare module JSX {
interface ElementAttributesProperty { props; }
}
declare module React {
class Component<T, U> { }
}
declare module "BaseComponent" {
export default class extends React.Component<any, {}> {
}
}
//@filename: consumer.tsx
/// <reference path="component.d.ts" />
import BaseComponent from 'BaseComponent';
class TestComponent extends React.Component<any, {}> {
render() {
return <BaseComponent />;
}
}