Skip to content

Commit 05d64cc

Browse files
monicatangfacebook-github-bot
authored andcommitted
update GraphQL parser to consume escaped characters
Summary: ### Context We got [feedback](https://fb.workplace.com/groups/relay.support/permalink/25937328725889064/) in Relay Support about some generated artifacts being deleted in D54762067 (when `parseData` was declared in a variable outside the component specifically). It turns out that the RegEx syntax added in the diff was not being parsed correctly by the GraphQL extractor. So, the GraphQL source text was not extracted from the file and the generated artifact was removed. ## This diff Adds logic to consume escaped characters. Note that comments and strings are already consumed generally. I also changed the iterator to be peekable. The example application for this diff is in the regex `/text\/*/`: without peeking, `consume_identifier` consumes `text\` though `\` should be used as an escape. It seems we've run into similar issues before which led us to consider switching to a stricter GraphQL parser (see e.g. D21256605 from 2020). Maybe we should revisit that idea? Reviewed By: evanyeung Differential Revision: D54879768 fbshipit-source-id: cccb3311acf7188b642c478f2a68f18d8d7eb66b
1 parent 6b807a4 commit 05d64cc

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

compiler/crates/extract-graphql/src/lib.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,15 @@ pub fn extract(input: &str) -> Vec<JavaScriptSourceFeature> {
174174
// }
175175
'"' => consume_string(&mut it, '"'),
176176
'\'' => consume_string(&mut it, '\''),
177+
'\\' => consume_escaped_char(&mut it),
177178
'/' => {
178-
match it.next() {
179+
match it.chars.peek() {
179180
Some((_, '/')) => {
181+
it.next();
180182
consume_line_comment(&mut it);
181183
}
182184
Some((_, '*')) => {
185+
it.next();
183186
let start = i;
184187
let line_index = it.line_index;
185188
let column_index = it.column_index;
@@ -213,13 +216,17 @@ pub fn extract(input: &str) -> Vec<JavaScriptSourceFeature> {
213216
res
214217
}
215218

219+
fn consume_escaped_char(it: &mut CharReader<'_>) {
220+
it.next();
221+
}
222+
216223
fn consume_identifier(it: &mut CharReader<'_>) {
217-
for (_, c) in it {
218-
match c {
219-
'a'..='z' | 'A'..='Z' | '_' | '0'..='9' => {}
220-
_ => {
221-
return;
224+
while it.chars.peek().is_some() {
225+
match it.chars.peek() {
226+
Some((_, 'a'..='z' | 'A'..='Z' | '_' | '0'..='9')) => {
227+
it.next();
222228
}
229+
_ => break,
223230
}
224231
}
225232
}

compiler/crates/extract-graphql/tests/extract/fixtures/regex.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ function MyComponent() {
1717
return <div>Test</div>;
1818
}
1919
==================================== OUTPUT ===================================
20+
graphql - line: 10, column: 24, text: <
21+
fragment Test on User {
22+
__typename
23+
}
24+
>

0 commit comments

Comments
 (0)