From e370540d73e49ea3d62474ed1ea1e518b9e99e6f Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sat, 19 Sep 2026 07:46:56 +0200 Subject: [PATCH 1/3] Skip rescript-schema-ppx and sury-ppx for unrelated sources Signed-off-by: Christoph Knittel --- CHANGELOG.md | 1 + rewatch/src/build/parse.rs | 74 ++++++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 890b5818c44..a85c33a8450 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,7 @@ #### :nail_care: Polish +- Avoid running `rescript-schema-ppx` and `sury-ppx` on source files without an `@schema` annotation. - Omit unnecessary parentheses around coercions where the surrounding syntax already delimits the expression, while preserving required grouping. https://github.com/rescript-lang/rescript/pull/8614 - Print external declarations in signatures and type errors with their processed attributes instead of the `"#rescript-external"` placeholder, and print inline constants using `@inline` syntax. https://github.com/rescript-lang/rescript/pull/8581 - Improve diagnostics for dynamic imports of local values and attempts to use `import` as a first-class value. https://github.com/rescript-lang/rescript/pull/8582 diff --git a/rewatch/src/build/parse.rs b/rewatch/src/build/parse.rs index 87944965ae3..9e26e09e105 100644 --- a/rewatch/src/build/parse.rs +++ b/rewatch/src/build/parse.rs @@ -483,20 +483,22 @@ fn generate_ast( result } +const SOURCE_TRIGGERED_PPXES: &[(&[&str], &str)] = &[ + (&["graphql-ppx", "graphql_ppx"], "%graphql"), + (&["spice"], "@spice"), + (&["rescript-relay"], "%relay"), + (&["re-formality"], "%form"), + (&["rescript-schema-ppx", "sury-ppx"], "@schema"), +]; + fn include_ppx(flag: &str, contents: &str) -> bool { if flag.contains("bisect") { return std::env::var("BISECT_ENABLE").is_ok(); } - if ((flag.contains("graphql-ppx") || flag.contains("graphql_ppx")) && !contents.contains("%graphql")) - || (flag.contains("spice") && !contents.contains("@spice")) - || (flag.contains("rescript-relay") && !contents.contains("%relay")) - || (flag.contains("re-formality") && !contents.contains("%form")) - { - return false; - }; - - true + SOURCE_TRIGGERED_PPXES + .iter() + .all(|(names, marker)| !names.iter().any(|name| flag.contains(name)) || contents.contains(marker)) } fn filter_ppx_flags( @@ -509,9 +511,61 @@ fn filter_ppx_flags( .iter() .filter(|flag| match flag { config::OneOrMore::Single(str) => include_ppx(str, contents), - config::OneOrMore::Multiple(str) => include_ppx(str.first().unwrap(), contents), + config::OneOrMore::Multiple(str) => { + str.first().is_some_and(|command| include_ppx(command, contents)) + } }) .map(|x| x.to_owned()) .collect::>>() }) } + +#[cfg(test)] +mod tests { + use super::{filter_ppx_flags, include_ppx}; + use crate::config::OneOrMore; + + #[test] + fn source_triggered_ppxes_only_run_for_matching_sources() { + for command in [ + "graphql-ppx", + "graphql_ppx", + "spice", + "rescript-relay", + "re-formality", + "rescript-schema-ppx", + "sury-ppx/bin", + ] { + assert!(!include_ppx(command, "let value = 1"), "{command}"); + } + + for (command, marker) in [ + ("graphql-ppx", "%graphql"), + ("graphql_ppx", "%graphql"), + ("spice", "@spice"), + ("rescript-relay", "%relay"), + ("re-formality", "%form"), + ("rescript-schema-ppx", "@schema"), + ("sury-ppx/bin", "@schema"), + ] { + assert!(include_ppx(command, marker), "{command}"); + } + + assert!(include_ppx("unconditional-ppx", "let value = 1")); + } + + #[test] + fn empty_ppx_commands_are_ignored() { + let flags = Some(vec![ + OneOrMore::Multiple(vec![]), + OneOrMore::Single("unconditional-ppx".to_string()), + ]); + let filtered = filter_ppx_flags(&flags, "let value = 1").unwrap(); + + assert_eq!(filtered.len(), 1); + assert!(matches!( + &filtered[0], + OneOrMore::Single(command) if command == "unconditional-ppx" + )); + } +} From 7d5a1ca507acda88d32ed12362f397e1438c7438 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sat, 19 Sep 2026 07:46:56 +0200 Subject: [PATCH 2/3] Clarify source-triggered PPX filtering Signed-off-by: Christoph Knittel --- CHANGELOG.md | 2 +- rewatch/src/build/parse.rs | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a85c33a8450..07fe599b59f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,7 +93,7 @@ #### :nail_care: Polish -- Avoid running `rescript-schema-ppx` and `sury-ppx` on source files without an `@schema` annotation. +- Avoid running `rescript-schema-ppx` and `sury-ppx` on source files without an `@schema` annotation. https://github.com/rescript-lang/rescript/pull/8662 - Omit unnecessary parentheses around coercions where the surrounding syntax already delimits the expression, while preserving required grouping. https://github.com/rescript-lang/rescript/pull/8614 - Print external declarations in signatures and type errors with their processed attributes instead of the `"#rescript-external"` placeholder, and print inline constants using `@inline` syntax. https://github.com/rescript-lang/rescript/pull/8581 - Improve diagnostics for dynamic imports of local values and attempts to use `import` as a first-class value. https://github.com/rescript-lang/rescript/pull/8582 diff --git a/rewatch/src/build/parse.rs b/rewatch/src/build/parse.rs index 9e26e09e105..2c503a47e51 100644 --- a/rewatch/src/build/parse.rs +++ b/rewatch/src/build/parse.rs @@ -491,7 +491,9 @@ const SOURCE_TRIGGERED_PPXES: &[(&[&str], &str)] = &[ (&["rescript-schema-ppx", "sury-ppx"], "@schema"), ]; -fn include_ppx(flag: &str, contents: &str) -> bool { +// Only skip PPXs whose transformations are known to require a source marker; +// unknown PPXs must keep running because they may transform unmarked sources. +fn should_run_ppx(flag: &str, contents: &str) -> bool { if flag.contains("bisect") { return std::env::var("BISECT_ENABLE").is_ok(); } @@ -510,10 +512,10 @@ fn filter_ppx_flags( flags .iter() .filter(|flag| match flag { - config::OneOrMore::Single(str) => include_ppx(str, contents), - config::OneOrMore::Multiple(str) => { - str.first().is_some_and(|command| include_ppx(command, contents)) - } + config::OneOrMore::Single(str) => should_run_ppx(str, contents), + config::OneOrMore::Multiple(str) => str + .first() + .is_some_and(|command| should_run_ppx(command, contents)), }) .map(|x| x.to_owned()) .collect::>>() @@ -522,7 +524,7 @@ fn filter_ppx_flags( #[cfg(test)] mod tests { - use super::{filter_ppx_flags, include_ppx}; + use super::{filter_ppx_flags, should_run_ppx}; use crate::config::OneOrMore; #[test] @@ -536,7 +538,7 @@ mod tests { "rescript-schema-ppx", "sury-ppx/bin", ] { - assert!(!include_ppx(command, "let value = 1"), "{command}"); + assert!(!should_run_ppx(command, "let value = 1"), "{command}"); } for (command, marker) in [ @@ -548,10 +550,10 @@ mod tests { ("rescript-schema-ppx", "@schema"), ("sury-ppx/bin", "@schema"), ] { - assert!(include_ppx(command, marker), "{command}"); + assert!(should_run_ppx(command, marker), "{command}"); } - assert!(include_ppx("unconditional-ppx", "let value = 1")); + assert!(should_run_ppx("unconditional-ppx", "let value = 1")); } #[test] From a6709fe1fde9a2632456520547272e76e3d1cbef Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Mon, 21 Sep 2026 19:39:34 +0200 Subject: [PATCH 3/3] Fix CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07fe599b59f..d444142eb85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ #### :nail_care: Polish +- Avoid running `rescript-schema-ppx` and `sury-ppx` on source files without an `@schema` annotation. https://github.com/rescript-lang/rescript/pull/8662 + #### :house: Internal # 13.0.0-alpha.6 @@ -93,7 +95,6 @@ #### :nail_care: Polish -- Avoid running `rescript-schema-ppx` and `sury-ppx` on source files without an `@schema` annotation. https://github.com/rescript-lang/rescript/pull/8662 - Omit unnecessary parentheses around coercions where the surrounding syntax already delimits the expression, while preserving required grouping. https://github.com/rescript-lang/rescript/pull/8614 - Print external declarations in signatures and type errors with their processed attributes instead of the `"#rescript-external"` placeholder, and print inline constants using `@inline` syntax. https://github.com/rescript-lang/rescript/pull/8581 - Improve diagnostics for dynamic imports of local values and attempts to use `import` as a first-class value. https://github.com/rescript-lang/rescript/pull/8582