@@ -57,10 +57,10 @@ use uv_pep440::{release_specifier_to_range, Operator, Version, VersionSpecifier}
57
57
use version_ranges:: Ranges ;
58
58
59
59
use crate :: marker:: lowering:: {
60
- LoweredMarkerValueExtra , LoweredMarkerValueString , LoweredMarkerValueVersion ,
60
+ LoweredMarkerValueExtra , LoweredMarkerValueString , LoweredMarkerValueVersion , Platform ,
61
61
} ;
62
62
use crate :: marker:: MarkerValueExtra ;
63
- use crate :: ExtraOperator ;
63
+ use crate :: { ExtraOperator , MarkerValueString } ;
64
64
use crate :: { MarkerExpression , MarkerOperator , MarkerValueVersion } ;
65
65
66
66
/// The global node interner.
@@ -260,6 +260,24 @@ impl InternerGuard<'_> {
260
260
} ,
261
261
Edges :: from_bool ( false ) ,
262
262
) ,
263
+ // A variable representing the output of a platform key. Edges correspond
264
+ // to disjoint platform ranges.
265
+ MarkerExpression :: String {
266
+ key : MarkerValueString :: PlatformSystem ,
267
+ operator,
268
+ value,
269
+ } => {
270
+ let platform = Platform :: from_platform_system ( value) ;
271
+ ( Variable :: Platform , Edges :: from_platform ( operator, platform) )
272
+ }
273
+ MarkerExpression :: String {
274
+ key : MarkerValueString :: SysPlatform ,
275
+ operator,
276
+ value,
277
+ } => {
278
+ let platform = Platform :: from_sys_platform ( value) ;
279
+ ( Variable :: Platform , Edges :: from_platform ( operator, platform) )
280
+ }
263
281
// A variable representing the output of a string key. Edges correspond
264
282
// to disjoint string ranges.
265
283
MarkerExpression :: String {
@@ -624,6 +642,8 @@ pub(crate) enum Variable {
624
642
Version ( LoweredMarkerValueVersion ) ,
625
643
/// A string marker, such as `os_name`.
626
644
String ( LoweredMarkerValueString ) ,
645
+ /// A platform marker, combining `sys_platform` with `platform_system`.
646
+ Platform ,
627
647
/// A variable representing a `<key> in <value>` expression for a particular
628
648
/// string marker and value.
629
649
In {
@@ -748,6 +768,11 @@ pub(crate) enum Edges {
748
768
String {
749
769
edges : SmallVec < ( Ranges < String > , NodeId ) > ,
750
770
} ,
771
+ // The edges of a platform variable, representing a disjoint set of ranges that cover
772
+ // the output space.
773
+ Platform {
774
+ edges : SmallVec < ( Ranges < Platform > , NodeId ) > ,
775
+ } ,
751
776
// The edges of a boolean variable, representing the values `true` (the `high` child)
752
777
// and `false` (the `low` child).
753
778
Boolean {
@@ -793,6 +818,24 @@ impl Edges {
793
818
}
794
819
}
795
820
821
+ /// Returns the [`Edges`] for a platform expression.
822
+ fn from_platform ( operator : MarkerOperator , value : Platform ) -> Edges {
823
+ let range: Ranges < Platform > = match operator {
824
+ MarkerOperator :: Equal => Ranges :: singleton ( value) ,
825
+ MarkerOperator :: NotEqual => Ranges :: singleton ( value) . complement ( ) ,
826
+ MarkerOperator :: GreaterThan => Ranges :: strictly_higher_than ( value) ,
827
+ MarkerOperator :: GreaterEqual => Ranges :: higher_than ( value) ,
828
+ MarkerOperator :: LessThan => Ranges :: strictly_lower_than ( value) ,
829
+ MarkerOperator :: LessEqual => Ranges :: lower_than ( value) ,
830
+ MarkerOperator :: TildeEqual => unreachable ! ( "string comparisons with ~= are ignored" ) ,
831
+ _ => unreachable ! ( "`in` and `contains` are treated as boolean variables" ) ,
832
+ } ;
833
+
834
+ Edges :: Platform {
835
+ edges : Edges :: from_range ( & range) ,
836
+ }
837
+ }
838
+
796
839
/// Returns the [`Edges`] for a version specifier.
797
840
fn from_specifier ( specifier : VersionSpecifier ) -> Edges {
798
841
let specifier = release_specifier_to_range ( normalize_specifier ( specifier) ) ;
@@ -901,6 +944,11 @@ impl Edges {
901
944
( Edges :: String { edges } , Edges :: String { edges : right_edges } ) => Edges :: String {
902
945
edges : Edges :: apply_ranges ( edges, parent, right_edges, right_parent, apply) ,
903
946
} ,
947
+ ( Edges :: Platform { edges } , Edges :: Platform { edges : right_edges } ) => {
948
+ Edges :: Platform {
949
+ edges : Edges :: apply_ranges ( edges, parent, right_edges, right_parent, apply) ,
950
+ }
951
+ }
904
952
// For boolean variables, we simply merge the low and high edges.
905
953
(
906
954
Edges :: Boolean { high, low } ,
@@ -1000,6 +1048,9 @@ impl Edges {
1000
1048
( Edges :: String { edges } , Edges :: String { edges : right_edges } ) => {
1001
1049
Edges :: is_disjoint_ranges ( edges, parent, right_edges, right_parent, interner)
1002
1050
}
1051
+ ( Edges :: Platform { edges } , Edges :: Platform { edges : right_edges } ) => {
1052
+ Edges :: is_disjoint_ranges ( edges, parent, right_edges, right_parent, interner)
1053
+ }
1003
1054
// For boolean variables, we simply check the low and high edges.
1004
1055
(
1005
1056
Edges :: Boolean { high, low } ,
@@ -1065,6 +1116,13 @@ impl Edges {
1065
1116
. map ( |( range, node) | ( range, f ( node. negate ( parent) ) ) )
1066
1117
. collect ( ) ,
1067
1118
} ,
1119
+ Edges :: Platform { edges : map } => Edges :: Platform {
1120
+ edges : map
1121
+ . iter ( )
1122
+ . cloned ( )
1123
+ . map ( |( range, node) | ( range, f ( node. negate ( parent) ) ) )
1124
+ . collect ( ) ,
1125
+ } ,
1068
1126
Edges :: Boolean { high, low } => Edges :: Boolean {
1069
1127
low : f ( low. negate ( parent) ) ,
1070
1128
high : f ( high. negate ( parent) ) ,
@@ -1081,7 +1139,10 @@ impl Edges {
1081
1139
Edges :: String { edges : map } => {
1082
1140
Either :: Left ( Either :: Right ( map. iter ( ) . map ( |( _, node) | * node) ) )
1083
1141
}
1084
- Edges :: Boolean { high, low } => Either :: Right ( [ * high, * low] . into_iter ( ) ) ,
1142
+ Edges :: Platform { edges : map } => {
1143
+ Either :: Right ( Either :: Left ( map. iter ( ) . map ( |( _, node) | * node) ) )
1144
+ }
1145
+ Edges :: Boolean { high, low } => Either :: Right ( Either :: Right ( [ * high, * low] . into_iter ( ) ) ) ,
1085
1146
}
1086
1147
}
1087
1148
@@ -1100,6 +1161,12 @@ impl Edges {
1100
1161
. map ( |( range, node) | ( range, node. not ( ) ) )
1101
1162
. collect ( ) ,
1102
1163
} ,
1164
+ Edges :: Platform { edges : map } => Edges :: Platform {
1165
+ edges : map
1166
+ . into_iter ( )
1167
+ . map ( |( range, node) | ( range, node. not ( ) ) )
1168
+ . collect ( ) ,
1169
+ } ,
1103
1170
Edges :: Boolean { high, low } => Edges :: Boolean {
1104
1171
high : high. not ( ) ,
1105
1172
low : low. not ( ) ,
0 commit comments