diff --git a/src/parser.js b/src/parser.js
index bfa7b1009..426fcbc40 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -53,20 +53,15 @@ function parseWithBabylon(text) {
}
function parseWithTypeScript(text) {
- // While we are working on typescript, we are putting it in devDependencies
- // so it shouldn't be picked up by static analysis
- const r = require;
- const parser = r("typescript-eslint-parser");
+ const jsx = isProbablyJsx(text);
try {
- return parser.parse(text, {
- loc: true,
- range: true,
- tokens: true,
- attachComment: true,
- ecmaFeatures: {
- jsx: isJsx(text)
- }
- });
+ try {
+ // Try passing with our best guess first.
+ return tryParseTypeScript(text, jsx);
+ } catch (e) {
+ // But if we get it wrong, try the opposite.
+ return tryParseTypeScript(text, !jsx);
+ }
} catch(e) {
throw createError(
e.message,
@@ -76,13 +71,27 @@ function parseWithTypeScript(text) {
}
}
+function tryParseTypeScript(text, jsx) {
+ // While we are working on typescript, we are putting it in devDependencies
+ // so it shouldn't be picked up by static analysis
+ const r = require;
+ const parser = r("typescript-eslint-parser");
+ return parser.parse(text, {
+ loc: true,
+ range: true,
+ tokens: true,
+ attachComment: true,
+ ecmaFeatures: { jsx }
+ });
+}
+
/**
* Use a naive regular expression until we address
* https://github.com/prettier/prettier/issues/1538
*/
-function isJsx(text) {
+function isProbablyJsx(text) {
return new RegExp([
- "()", // Contains ""
+ "(^[^\"'`]*)", // Contains "" when probably not in a string
"|",
"(^[^/]{2}.*\/>)" // Contains "/>" on line not starting with "//"
].join(""), "m").test(text);
diff --git a/tests/typescript_tsx/__snapshots__/jsfmt.spec.js.snap b/tests/typescript_tsx/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000..8168e9ea9
--- /dev/null
+++ b/tests/typescript_tsx/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,40 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`not-react.ts 1`] = `
+///
+
+type ul = any;
+const somethingElse = 1;
+const thing =
somethingElse;
+const div = "";
+const h1 = \`Hi
\`;
+const footer = '';
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+
+type ul = any;
+const somethingElse = 1;
+const thing = somethingElse;
+const div = "";
+const h1 = \`Hi
\`;
+const footer = "";
+
+`;
+
+exports[`react.tsx 1`] = `
+const MyCoolList = ({ things }) =>
+
+ {things.map(MyCoolThing)}
+
;
+
+const MyCoolThing = ({ thingo }) => - {thingo}
;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const MyCoolList = ({ things }) => (
+
+ {things.map(MyCoolThing)}
+
+);
+
+const MyCoolThing = ({ thingo }) => - {thingo}
;
+
+`;
diff --git a/tests/typescript_tsx/jsfmt.spec.js b/tests/typescript_tsx/jsfmt.spec.js
new file mode 100644
index 000000000..379b0d723
--- /dev/null
+++ b/tests/typescript_tsx/jsfmt.spec.js
@@ -0,0 +1 @@
+run_spec(__dirname, {parser: "typescript"});
diff --git a/tests/typescript_tsx/not-react.ts b/tests/typescript_tsx/not-react.ts
new file mode 100644
index 000000000..b1a4036a3
--- /dev/null
+++ b/tests/typescript_tsx/not-react.ts
@@ -0,0 +1,8 @@
+///
+
+type ul = any;
+const somethingElse = 1;
+const thing = somethingElse;
+const div = "";
+const h1 = `Hi
`;
+const footer = '';
diff --git a/tests/typescript_tsx/react.tsx b/tests/typescript_tsx/react.tsx
new file mode 100644
index 000000000..188eb4c3d
--- /dev/null
+++ b/tests/typescript_tsx/react.tsx
@@ -0,0 +1,6 @@
+const MyCoolList = ({ things }) =>
+
+ {things.map(MyCoolThing)}
+
;
+
+const MyCoolThing = ({ thingo }) => - {thingo}
;
diff --git a/tests_config/run_spec.js b/tests_config/run_spec.js
index 12249c5b7..c89e1339b 100644
--- a/tests_config/run_spec.js
+++ b/tests_config/run_spec.js
@@ -1,6 +1,7 @@
"use strict";
const fs = require("fs");
+const extname = require("path").extname;
const prettier = require("../");
const types = require("../src/ast-types");
const parser = require("../src/parser");
@@ -25,10 +26,8 @@ function removeEmptyStatements(ast) {
function run_spec(dirname, options, additionalParsers) {
fs.readdirSync(dirname).forEach(filename => {
- if (
- (filename.endsWith(".js") || filename.endsWith(".ts")) &&
- filename !== "jsfmt.spec.js"
- ) {
+ const extension = extname(filename);
+ if (/^\.[jt]sx?$/.test(extension) && filename !== "jsfmt.spec.js") {
const path = dirname + "/" + filename;
if (!RUN_AST_TESTS) {