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