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:
commit
4888e4f958
21 changed files with 257 additions and 14 deletions
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3298,7 +3298,8 @@
|
|||
export const enum JsxEmit {
|
||||
None = 0,
|
||||
Preserve = 1,
|
||||
React = 2
|
||||
React = 2,
|
||||
ReactNative = 3
|
||||
}
|
||||
|
||||
export const enum NewLineKind {
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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
|
||||
}]
|
||||
|
|
|
@ -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 {
|
|||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
11
tests/baselines/reference/es3-jsx-preserve.js
Normal file
11
tests/baselines/reference/es3-jsx-preserve.js
Normal 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>;
|
11
tests/baselines/reference/es3-jsx-preserve.symbols
Normal file
11
tests/baselines/reference/es3-jsx-preserve.symbols
Normal 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)
|
||||
|
||||
|
13
tests/baselines/reference/es3-jsx-preserve.types
Normal file
13
tests/baselines/reference/es3-jsx-preserve.types
Normal 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
|
||||
|
||||
|
11
tests/baselines/reference/es3-jsx-react-native.js
Normal file
11
tests/baselines/reference/es3-jsx-react-native.js
Normal 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>;
|
11
tests/baselines/reference/es3-jsx-react-native.symbols
Normal file
11
tests/baselines/reference/es3-jsx-react-native.symbols
Normal 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)
|
||||
|
||||
|
13
tests/baselines/reference/es3-jsx-react-native.types
Normal file
13
tests/baselines/reference/es3-jsx-react-native.types
Normal 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
|
||||
|
||||
|
11
tests/baselines/reference/es3-jsx-react.js
Normal file
11
tests/baselines/reference/es3-jsx-react.js
Normal 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);
|
11
tests/baselines/reference/es3-jsx-react.symbols
Normal file
11
tests/baselines/reference/es3-jsx-react.symbols
Normal 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)
|
||||
|
||||
|
13
tests/baselines/reference/es3-jsx-react.types
Normal file
13
tests/baselines/reference/es3-jsx-react.types
Normal 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
|
||||
|
||||
|
9
tests/cases/compiler/es3-jsx-preserve.tsx
Normal file
9
tests/cases/compiler/es3-jsx-preserve.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
// @target: ES3
|
||||
// @sourcemap: false
|
||||
// @declaration: false
|
||||
// @jsx: preserve
|
||||
|
||||
const React: any = null;
|
||||
|
||||
const elem = <div></div>;
|
||||
|
9
tests/cases/compiler/es3-jsx-react-native.tsx
Normal file
9
tests/cases/compiler/es3-jsx-react-native.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
// @target: ES3
|
||||
// @sourcemap: false
|
||||
// @declaration: false
|
||||
// @jsx: react-native
|
||||
|
||||
const React: any = null;
|
||||
|
||||
const elem = <div></div>;
|
||||
|
9
tests/cases/compiler/es3-jsx-react.tsx
Normal file
9
tests/cases/compiler/es3-jsx-react.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
// @target: ES3
|
||||
// @sourcemap: false
|
||||
// @declaration: false
|
||||
// @jsx: react
|
||||
|
||||
const React: any = null;
|
||||
|
||||
const elem = <div></div>;
|
||||
|
|
@ -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 {
|
|||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue