Skip to content

Commit 3d3f07a

Browse files
authored
Merge pull request github#18658 from asgerf/js/jsx-parser-first-attempt
JS: Use JSX syntax in first attempt when extension is .jsx
2 parents 90944d5 + 09270f4 commit 3d3f07a

File tree

8 files changed

+413
-8
lines changed

8 files changed

+413
-8
lines changed

javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ public Pair<Label, ParseResultInfo> extract(
5656

5757
SourceType sourceType = establishSourceType(source, true);
5858

59+
String extension = textualExtractor.getLocationManager().getSourceFileExtension();
60+
5961
JSParser.Result parserRes =
60-
JSParser.parse(config, sourceType, source, textualExtractor.getMetrics());
62+
JSParser.parse(config, sourceType, extension, source, textualExtractor.getMetrics());
6163

6264
// Check if we guessed wrong with the regex in `establishSourceType`, (which could
6365
// happen due to a block-comment line starting with ' import').
@@ -74,7 +76,7 @@ public Pair<Label, ParseResultInfo> extract(
7476
if (wrongGuess) {
7577
sourceType = SourceType.SCRIPT;
7678
parserRes =
77-
JSParser.parse(config, sourceType, source, textualExtractor.getMetrics());
79+
JSParser.parse(config, sourceType, extension, source, textualExtractor.getMetrics());
7880
}
7981
}
8082

javascript/extractor/src/com/semmle/js/parser/JSParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ public List<ParseError> getErrors() {
6868
}
6969

7070
public static Result parse(
71-
ExtractorConfig config, SourceType sourceType, String source, ExtractionMetrics metrics) {
71+
ExtractorConfig config, SourceType sourceType, String extension, String source, ExtractionMetrics metrics) {
7272
metrics.startPhase(ExtractionPhase.JSParser_parse);
73-
Result result = JcornWrapper.parse(config, sourceType, source);
73+
Result result = JcornWrapper.parse(config, sourceType, extension, source);
7474
metrics.stopPhase(ExtractionPhase.JSParser_parse);
7575
return result;
7676
}

javascript/extractor/src/com/semmle/js/parser/JcornWrapper.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@
1414
import com.semmle.js.extractor.ExtractorConfig.SourceType;
1515

1616
public class JcornWrapper {
17+
public static boolean alwaysParseWithJsx(String extension) {
18+
// Note that .tsx is not relevant here since this is specifically for the JS parser.
19+
return extension.equals(".jsx");
20+
}
21+
1722
/** Parse source code as a program. */
1823
public static JSParser.Result parse(
19-
ExtractorConfig config, SourceType sourceType, String source) {
24+
ExtractorConfig config, SourceType sourceType, String extension, String source) {
2025
ECMAVersion ecmaVersion = config.getEcmaVersion();
2126
List<Comment> comments = new ArrayList<>();
2227
List<Token> tokens = new ArrayList<>();
@@ -32,7 +37,11 @@ public static JSParser.Result parse(
3237

3338
Program program = null;
3439
List<ParseError> errors = new ArrayList<>();
35-
40+
41+
// If the file extension implies JSX syntax, use that in the first parsing attempt.
42+
// This enables us to parse JSX files that the Flow parser cannot handle due to ambiguous syntax.
43+
if (alwaysParseWithJsx(extension)) options = new JSXOptions(options);
44+
3645
try {
3746
try {
3847
// First try to parse as a regular JavaScript program.

javascript/extractor/test/com/semmle/js/extractor/test/ES2015DetectorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class ES2015DetectorTests {
1616
private static final ExtractorConfig CONFIG = new ExtractorConfig(true);
1717

1818
private void isES2015(String src, boolean expected) {
19-
Result res = JSParser.parse(CONFIG, SourceType.MODULE, src, new ExtractionMetrics());
19+
Result res = JSParser.parse(CONFIG, SourceType.MODULE, ".jsx", src, new ExtractionMetrics());
2020
Node ast = res.getAST();
2121
Assert.assertNotNull(ast);
2222
Assert.assertTrue(ES2015Detector.looksLikeES2015(ast) == expected);

javascript/extractor/test/com/semmle/js/extractor/test/NodeJSDetectorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class NodeJSDetectorTests {
1616
private static final ExtractorConfig CONFIG = new ExtractorConfig(true);
1717

1818
private void isNodeJS(String src, boolean expected) {
19-
Result res = JSParser.parse(CONFIG, SourceType.SCRIPT, src, new ExtractionMetrics());
19+
Result res = JSParser.parse(CONFIG, SourceType.SCRIPT, ".jsx", src, new ExtractionMetrics());
2020
Node ast = res.getAST();
2121
Assert.assertNotNull(ast);
2222
Assert.assertTrue(NodeJSDetector.looksLikeNodeJS(ast) == expected);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function foo() {
2+
let x = <div></div>;
3+
return true ? (null, null) : e => { };
4+
}

0 commit comments

Comments
 (0)