Merge pull request #13636 from ds300/preserve-jsx-but-output-.js-files

Add option to output .js files while preserving jsx
This commit is contained in:
Mohamed Hegazy 2017-01-23 23:22:45 -08:00 committed by GitHub
commit 4888e4f958
21 changed files with 257 additions and 14 deletions

View file

@ -67,10 +67,11 @@ namespace ts {
name: "jsx",
type: createMapFromTemplate({
"preserve": JsxEmit.Preserve,
"react-native": JsxEmit.ReactNative,
"react": JsxEmit.React
}),
paramType: Diagnostics.KIND,
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react,
},
{
name: "reactNamespace",

View file

@ -2713,7 +2713,7 @@
"category": "Message",
"code": 6079
},
"Specify JSX code generation: 'preserve' or 'react'": {
"Specify JSX code generation: 'preserve', 'react-native', or 'react'": {
"category": "Message",
"code": 6080
},

View file

@ -11,10 +11,10 @@ namespace ts {
export function transformES5(context: TransformationContext) {
const compilerOptions = context.getCompilerOptions();
// enable emit notification only if using --jsx preserve
// enable emit notification only if using --jsx preserve or react-native
let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
let noSubstitution: boolean[];
if (compilerOptions.jsx === JsxEmit.Preserve) {
if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) {
previousOnEmitNode = context.onEmitNode;
context.onEmitNode = onEmitNode;
context.enableEmitNotification(SyntaxKind.JsxOpeningElement);
@ -116,4 +116,4 @@ namespace ts {
return undefined;
}
}
}
}

View file

@ -3298,7 +3298,8 @@
export const enum JsxEmit {
None = 0,
Preserve = 1,
React = 2
React = 2,
ReactNative = 3
}
export const enum NewLineKind {

View file

@ -87,7 +87,7 @@ namespace ts {
start: undefined,
length: undefined,
}, {
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'",
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,

View file

@ -94,7 +94,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]

View file

@ -909,6 +909,31 @@ namespace ts {
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("with jsx=react-native, allowJs=false", () => {
const json = {
compilerOptions: {
jsx: "react-native",
allowJs: false
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.ReactNative,
allowJs: false
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("with jsx=none, allowJs=true", () => {
const json = {
compilerOptions: {
@ -961,6 +986,33 @@ namespace ts {
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("with jsx=react-native, allowJs=true", () => {
const json = {
compilerOptions: {
jsx: "react-native",
allowJs: true
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.ReactNative,
allowJs: true
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
"c:/dev/d.js",
"c:/dev/e.jsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assertParsed(actual, expected);
});
it("exclude .min.js files using wildcards", () => {
const json = {
compilerOptions: {
@ -1306,4 +1358,4 @@ namespace ts {
});
});
});
}
}

View file

@ -417,7 +417,7 @@ namespace ts.server.protocol {
startOffset: number;
/**
* Position (can be specified instead of line/offset pair)
* Position (can be specified instead of line/offset pair)
*/
/* @internal */
startPosition?: number;
@ -433,7 +433,7 @@ namespace ts.server.protocol {
endOffset: number;
/**
* Position (can be specified instead of line/offset pair)
* Position (can be specified instead of line/offset pair)
*/
/* @internal */
endPosition?: number;
@ -445,7 +445,7 @@ namespace ts.server.protocol {
}
/**
* Response for GetCodeFixes request.
* Response for GetCodeFixes request.
*/
export interface GetCodeFixesResponse extends Response {
body?: CodeAction[];
@ -2272,10 +2272,11 @@ namespace ts.server.protocol {
export namespace JsxEmit {
export type None = "None";
export type Preserve = "Preserve";
export type ReactNative = "ReactNative";
export type React = "React";
}
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative;
export namespace ModuleKind {
export type None = "None";

View file

@ -0,0 +1,11 @@
//// [es3-jsx-preserve.tsx]
const React: any = null;
const elem = <div></div>;
//// [es3-jsx-preserve.jsx]
var React = null;
var elem = <div></div>;

View file

@ -0,0 +1,11 @@
=== tests/cases/compiler/es3-jsx-preserve.tsx ===
const React: any = null;
>React : Symbol(React, Decl(es3-jsx-preserve.tsx, 1, 5))
const elem = <div></div>;
>elem : Symbol(elem, Decl(es3-jsx-preserve.tsx, 3, 5))
>div : Symbol(unknown)
>div : Symbol(unknown)

View file

@ -0,0 +1,13 @@
=== tests/cases/compiler/es3-jsx-preserve.tsx ===
const React: any = null;
>React : any
>null : null
const elem = <div></div>;
>elem : any
><div></div> : any
>div : any
>div : any

View file

@ -0,0 +1,11 @@
//// [es3-jsx-react-native.tsx]
const React: any = null;
const elem = <div></div>;
//// [es3-jsx-react-native.js]
var React = null;
var elem = <div></div>;

View file

@ -0,0 +1,11 @@
=== tests/cases/compiler/es3-jsx-react-native.tsx ===
const React: any = null;
>React : Symbol(React, Decl(es3-jsx-react-native.tsx, 1, 5))
const elem = <div></div>;
>elem : Symbol(elem, Decl(es3-jsx-react-native.tsx, 3, 5))
>div : Symbol(unknown)
>div : Symbol(unknown)

View file

@ -0,0 +1,13 @@
=== tests/cases/compiler/es3-jsx-react-native.tsx ===
const React: any = null;
>React : any
>null : null
const elem = <div></div>;
>elem : any
><div></div> : any
>div : any
>div : any

View file

@ -0,0 +1,11 @@
//// [es3-jsx-react.tsx]
const React: any = null;
const elem = <div></div>;
//// [es3-jsx-react.js]
var React = null;
var elem = React.createElement("div", null);

View file

@ -0,0 +1,11 @@
=== tests/cases/compiler/es3-jsx-react.tsx ===
const React: any = null;
>React : Symbol(React, Decl(es3-jsx-react.tsx, 1, 5))
const elem = <div></div>;
>elem : Symbol(elem, Decl(es3-jsx-react.tsx, 3, 5))
>div : Symbol(unknown)
>div : Symbol(unknown)

View file

@ -0,0 +1,13 @@
=== tests/cases/compiler/es3-jsx-react.tsx ===
const React: any = null;
>React : any
>null : null
const elem = <div></div>;
>elem : any
><div></div> : any
>div : any
>div : any

View file

@ -0,0 +1,9 @@
// @target: ES3
// @sourcemap: false
// @declaration: false
// @jsx: preserve
const React: any = null;
const elem = <div></div>;

View file

@ -0,0 +1,9 @@
// @target: ES3
// @sourcemap: false
// @declaration: false
// @jsx: react-native
const React: any = null;
const elem = <div></div>;

View file

@ -0,0 +1,9 @@
// @target: ES3
// @sourcemap: false
// @declaration: false
// @jsx: react
const React: any = null;
const elem = <div></div>;

View file

@ -898,6 +898,33 @@ namespace ts {
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
it("with jsx=react-native, allowJs=false", () => {
const json = {
compilerOptions: {
jsx: "react-native",
allowJs: false
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.ReactNative,
allowJs: false
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
it("with jsx=none, allowJs=true", () => {
const json = {
compilerOptions: {
@ -954,6 +981,35 @@ namespace ts {
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
it("with jsx=react-native, allowJs=true", () => {
const json = {
compilerOptions: {
jsx: "react-native",
allowJs: true
}
};
const expected: ts.ParsedCommandLine = {
options: {
jsx: ts.JsxEmit.ReactNative,
allowJs: true
},
errors: [],
fileNames: [
"c:/dev/a.ts",
"c:/dev/b.tsx",
"c:/dev/c.tsx",
"c:/dev/d.js",
"c:/dev/e.jsx",
],
wildcardDirectories: {
"c:/dev": ts.WatchDirectoryFlags.Recursive
}
};
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
assert.deepEqual(actual.fileNames, expected.fileNames);
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
assert.deepEqual(actual.errors, expected.errors);
});
describe("with trailing recursive directory", () => {
it("in includes", () => {
const json = {
@ -1149,4 +1205,4 @@ namespace ts {
});
});
});
}
}