77use enum_map:: Enum ;
88use exhaust:: Exhaust ;
99use serde:: Serialize ;
10+ use whippit:: reexport:: chumsky:: { error:: Rich , input:: Emitter , span:: SimpleSpan } ;
1011
1112/// The strict subset of WPT property conditionals that can be handled with `moz-webgpu-cts`.
1213///
@@ -27,7 +28,8 @@ pub struct Applicability {
2728pub enum Environment {
2829 Windows ,
2930 Linux ,
30- MacOs ,
31+ MacOsIntel ,
32+ MacOsArm ,
3133}
3234
3335/// The subset of browser build profiles can be handled by `moz-webgpu-cts`. Part of
@@ -40,3 +42,254 @@ pub enum BuildProfile {
4042 Debug ,
4143 Optimized ,
4244}
45+
46+ impl Environment {
47+ fn os ( self ) -> Os {
48+ match self {
49+ Self :: Windows => Os :: Windows ,
50+ Self :: Linux => Os :: Linux ,
51+ Self :: MacOsIntel => Os :: MacOs ,
52+ Self :: MacOsArm => Os :: MacOs ,
53+ }
54+ }
55+
56+ fn processor ( self ) -> Option < Processor > {
57+ match self {
58+ Self :: Windows | Self :: Linux => None ,
59+ Self :: MacOsIntel => Some ( Processor :: X86_64 ) ,
60+ Self :: MacOsArm => Some ( Processor :: Arm ) ,
61+ }
62+ }
63+
64+ fn from_mac_os ( processor : Processor ) -> Self {
65+ match processor {
66+ Processor :: X86_64 => Self :: MacOsIntel ,
67+ Processor :: Arm => Self :: MacOsArm ,
68+ }
69+ }
70+ }
71+
72+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
73+ enum Processor {
74+ X86_64 ,
75+ Arm ,
76+ }
77+
78+ impl Processor {
79+ pub fn from_ident ( s : & str ) -> Option < Self > {
80+ match s {
81+ "x86_64" => Some ( Self :: X86_64 ) ,
82+ "aarch64" => Some ( Self :: Arm ) ,
83+ _ => None ,
84+ }
85+ }
86+
87+ pub fn to_ident ( & self ) -> & ' static str {
88+ match self {
89+ Self :: X86_64 => "x86_64" ,
90+ Self :: Arm => "aarch64" ,
91+ }
92+ }
93+ }
94+
95+ // TODO: rename `Environment` to `Environment`
96+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
97+ enum Os {
98+ Linux ,
99+ Windows ,
100+ MacOs ,
101+ }
102+
103+ impl Os {
104+ pub fn from_ident ( s : & str ) -> Option < Self > {
105+ match s {
106+ "linux" => Some ( Self :: Linux ) ,
107+ "win" => Some ( Self :: Windows ) ,
108+ "mac" => Some ( Self :: MacOs ) ,
109+ _ => None ,
110+ }
111+ }
112+
113+ pub fn to_ident ( & self ) -> & ' static str {
114+ match self {
115+ Self :: Linux => "linux" ,
116+ Self :: Windows => "win" ,
117+ Self :: MacOs => "mac" ,
118+ }
119+ }
120+ }
121+
122+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
123+ enum ApplicabilityRule {
124+ Os ( Os ) ,
125+ Processor ( Processor ) ,
126+ Debug { inverted : bool } ,
127+ }
128+
129+ enum IncompletePlatform {
130+ UnknownProcessor {
131+ span : SimpleSpan ,
132+ processor : Processor ,
133+ } ,
134+ MacOs {
135+ span : SimpleSpan ,
136+ } ,
137+ }
138+
139+ enum EnvironmentMatcher {
140+ Finalized {
141+ environment : Environment ,
142+ os_span : SimpleSpan ,
143+ processor_span : Option < SimpleSpan > ,
144+ } ,
145+ Incomplete ( IncompletePlatform ) ,
146+ }
147+
148+ enum ApplicabilityParseError {
149+ ProcessorFoundAfterIndependentOs {
150+ os : Os ,
151+ os_span : SimpleSpan ,
152+ processor : Processor ,
153+ processor_span : SimpleSpan ,
154+ } ,
155+ }
156+
157+ struct ApplicabilityBuilder {
158+ environment : Option < EnvironmentMatcher > ,
159+ build_profile : Option < ( SimpleSpan , BuildProfile ) > ,
160+ }
161+
162+ impl ApplicabilityBuilder {
163+ pub fn handle_rule < ' a > (
164+ & mut self ,
165+ rule : ApplicabilityRule ,
166+ span : SimpleSpan ,
167+ emitter : & mut Emitter < Rich < ' _ , char > > ,
168+ ) -> Result < ( ) , ( ) > {
169+ let Self {
170+ environment : platform,
171+ build_profile,
172+ } = & * self ;
173+ let already_got_os_err = |prev_span, span| todo ! ( ) ;
174+ let processor_with_independent_os_err =
175+ |os : Os , os_span, processor : Processor , processor_span| {
176+ todo ! (
177+ "`processor` comparison is not allowed when `os == {:?}`" ,
178+ os. to_ident( )
179+ )
180+ } ;
181+ let check_for_dupe_processors = |first, first_span, second, second_span| {
182+ if first == second {
183+ todo ! ( "emit warning" )
184+ } else {
185+ todo ! ( "contradictory `processor` statements" )
186+ }
187+ } ;
188+ match rule {
189+ ApplicabilityRule :: Os ( name) => {
190+ self . environment = Some ( match ( platform, name) {
191+ (
192+ Some ( EnvironmentMatcher :: Finalized {
193+ os_span : prev_span, ..
194+ } ) ,
195+ _,
196+ )
197+ | (
198+ Some ( EnvironmentMatcher :: Incomplete ( IncompletePlatform :: MacOs {
199+ span : prev_span,
200+ } ) ) ,
201+ _,
202+ ) => return already_got_os_err ( prev_span, span) ,
203+ ( None , platform @ ( Os :: Linux | Os :: Windows ) ) => EnvironmentMatcher :: Finalized {
204+ environment : match platform {
205+ Os :: Linux => Environment :: Linux ,
206+ Os :: Windows => Environment :: Windows ,
207+ Os :: MacOs => unreachable ! ( ) ,
208+ } ,
209+ os_span : span,
210+ processor_span : None ,
211+ } ,
212+ ( None , Os :: MacOs ) => todo ! ( ) ,
213+ (
214+ Some ( EnvironmentMatcher :: Incomplete (
215+ IncompletePlatform :: UnknownProcessor {
216+ span : processor_span,
217+ processor,
218+ } ,
219+ ) ) ,
220+ Os :: MacOs ,
221+ ) => EnvironmentMatcher :: Finalized {
222+ environment : match processor {
223+ Processor :: X86_64 => Environment :: MacOsIntel ,
224+ Processor :: Arm => Environment :: MacOsArm ,
225+ } ,
226+ os_span : span,
227+ processor_span : Some ( * processor_span) ,
228+ } ,
229+ (
230+ Some ( EnvironmentMatcher :: Incomplete (
231+ IncompletePlatform :: UnknownProcessor {
232+ span : processor_span,
233+ processor,
234+ } ,
235+ ) ) ,
236+ os @ ( Os :: Linux | Os :: Windows ) ,
237+ ) => {
238+ return processor_with_independent_os_err (
239+ os,
240+ span,
241+ * processor,
242+ * processor_span,
243+ )
244+ }
245+ } )
246+ }
247+ ApplicabilityRule :: Processor ( processor) => {
248+ self . environment = Some ( match platform {
249+ Some ( EnvironmentMatcher :: Finalized {
250+ environment : platform,
251+ os_span,
252+ processor_span,
253+ } ) => {
254+ if let Some ( processor_span) = processor_span {
255+ check_for_dupe_processors (
256+ platform. processor ( ) . unwrap ( ) ,
257+ * processor_span,
258+ processor,
259+ span,
260+ ) ?;
261+ return Ok ( ( ) ) ;
262+ } else {
263+ return processor_with_independent_os_err (
264+ platform. os ( ) ,
265+ * os_span,
266+ processor,
267+ span,
268+ ) ;
269+ }
270+ }
271+ Some ( EnvironmentMatcher :: Incomplete ( IncompletePlatform :: MacOs {
272+ span : os_span,
273+ } ) ) => EnvironmentMatcher :: Finalized {
274+ environment : Environment :: from_mac_os ( processor) ,
275+ os_span : * os_span,
276+ processor_span : Some ( span) ,
277+ } ,
278+ Some ( EnvironmentMatcher :: Incomplete (
279+ IncompletePlatform :: UnknownProcessor {
280+ span : prev_span,
281+ processor : prev_processor,
282+ } ,
283+ ) ) => {
284+ check_for_dupe_processors ( * prev_processor, * prev_span, processor, span) ?;
285+ return Ok ( ( ) ) ;
286+ }
287+ None => todo ! ( ) ,
288+ } )
289+ }
290+ ApplicabilityRule :: Debug { inverted } => todo ! ( ) ,
291+ }
292+ return Ok ( ( ) ) ;
293+ }
294+ pub fn into_applicability ( self ) -> Result < Applicability , ( ) > { }
295+ }
0 commit comments