@@ -1145,6 +1145,9 @@ impl Printer<'_> {
1145
1145
fn string_literal_style ( & self ) -> pretty:: Styles {
1146
1146
pretty:: Styles :: color ( pretty:: palettes:: simple:: RED )
1147
1147
}
1148
+ fn string_literal_escape_style ( & self ) -> pretty:: Styles {
1149
+ pretty:: Styles :: color ( pretty:: palettes:: simple:: ORANGE )
1150
+ }
1148
1151
fn declarative_keyword_style ( & self ) -> pretty:: Styles {
1149
1152
pretty:: Styles :: color ( pretty:: palettes:: simple:: BLUE )
1150
1153
}
@@ -1188,9 +1191,54 @@ impl Printer<'_> {
1188
1191
}
1189
1192
1190
1193
impl < ' a > Printer < ' a > {
1191
- /// Pretty-print a `name: ` style "named argument" prefix .
1194
+ /// Pretty-print a string literal with escaping and styling .
1192
1195
//
1193
- // FIXME(eddyb) add methods like this for all styled text (e.g. literals).
1196
+ // FIXME(eddyb) add methods like this for all styled text (e.g. numeric literals).
1197
+ fn pretty_string_literal ( & self , s : & str ) -> pretty:: Fragment {
1198
+ // HACK(eddyb) this is somewhat inefficient, but we need to allocate a
1199
+ // `String` for every piece anyway, so might as well make it convenient.
1200
+ pretty:: Fragment :: new (
1201
+ // HACK(eddyb) this allows aligning the actual string contents,
1202
+ // (see `c == '\n'` special-casing below for when this applies).
1203
+ ( s. contains ( '\n' ) . then_some ( Either :: Left ( ' ' ) ) . into_iter ( ) )
1204
+ . chain ( [ Either :: Left ( '"' ) ] )
1205
+ . chain ( s. chars ( ) . flat_map ( |c| {
1206
+ let escaped = c. escape_debug ( ) ;
1207
+ let maybe_escaped = if c == '\'' {
1208
+ // Unescape single quotes, we're in a double-quoted string.
1209
+ assert_eq ! ( escaped. collect_tuple( ) , Some ( ( '\\' , c) ) ) ;
1210
+ Either :: Left ( c)
1211
+ } else if let Some ( ( single, ) ) = escaped. clone ( ) . collect_tuple ( ) {
1212
+ assert_eq ! ( single, c) ;
1213
+ Either :: Left ( c)
1214
+ } else {
1215
+ assert_eq ! ( escaped. clone( ) . next( ) , Some ( '\\' ) ) ;
1216
+ Either :: Right ( escaped)
1217
+ } ;
1218
+
1219
+ // HACK(eddyb) move escaped `\n` to the start of a new line,
1220
+ // using Rust's trailing `\` on the previous line, which eats
1221
+ // all following whitespace (and only stops at the escape).
1222
+ let extra_prefix_unescaped = if c == '\n' { "\\ \n " } else { "" } ;
1223
+
1224
+ ( extra_prefix_unescaped. chars ( ) . map ( Either :: Left ) ) . chain ( [ maybe_escaped] )
1225
+ } ) )
1226
+ . chain ( [ Either :: Left ( '"' ) ] )
1227
+ . group_by ( |maybe_escaped| maybe_escaped. is_right ( ) )
1228
+ . into_iter ( )
1229
+ . map ( |( escaped, group) | {
1230
+ if escaped {
1231
+ self . string_literal_escape_style ( )
1232
+ . apply ( group. flat_map ( Either :: unwrap_right) . collect :: < String > ( ) )
1233
+ } else {
1234
+ self . string_literal_style ( )
1235
+ . apply ( group. map ( Either :: unwrap_left) . collect :: < String > ( ) )
1236
+ }
1237
+ } ) ,
1238
+ )
1239
+ }
1240
+
1241
+ /// Pretty-print a `name: ` style "named argument" prefix.
1194
1242
fn pretty_named_argument_prefix ( & self , name : impl Into < Cow < ' static , str > > ) -> pretty:: Fragment {
1195
1243
// FIXME(eddyb) avoid the cost of allocating here.
1196
1244
self . named_argument_label_style ( )
@@ -1835,9 +1883,9 @@ impl Print for spv::Dialect {
1835
1883
printer. pretty_named_argument_prefix ( "extensions" ) ,
1836
1884
pretty:: join_comma_sep (
1837
1885
"{" ,
1838
- extensions. iter ( ) . map ( |ext| {
1839
- printer . string_literal_style ( ) . apply ( format ! ( "{ext:?}" ) )
1840
- } ) ,
1886
+ extensions
1887
+ . iter ( )
1888
+ . map ( |ext| printer . pretty_string_literal ( ext ) ) ,
1841
1889
"}" ,
1842
1890
) ,
1843
1891
] )
@@ -1991,13 +2039,15 @@ impl Print for spv::ModuleDebugInfo {
1991
2039
. iter ( )
1992
2040
. map ( |( & file, contents) | {
1993
2041
pretty:: Fragment :: new ( [
1994
- printer. string_literal_style ( ) . apply (
1995
- format ! ( "{:?}" , & printer. cx[ file] ) ,
2042
+ printer. pretty_string_literal (
2043
+ & printer. cx [ file] ,
2044
+ ) ,
2045
+ pretty:: join_space (
2046
+ ":" ,
2047
+ [ printer. pretty_string_literal (
2048
+ contents,
2049
+ ) ] ,
1996
2050
) ,
1997
- ": " . into ( ) ,
1998
- printer
1999
- . string_literal_style ( )
2000
- . apply ( format ! ( "{contents:?}" ) ) ,
2001
2051
] )
2002
2052
} )
2003
2053
. map ( |entry| {
@@ -2026,9 +2076,9 @@ impl Print for spv::ModuleDebugInfo {
2026
2076
printer. pretty_named_argument_prefix ( "source_extensions" ) ,
2027
2077
pretty:: join_comma_sep (
2028
2078
"[" ,
2029
- source_extensions. iter ( ) . map ( |ext| {
2030
- printer . string_literal_style ( ) . apply ( format ! ( "{ext:?}" ) )
2031
- } ) ,
2079
+ source_extensions
2080
+ . iter ( )
2081
+ . map ( |ext| printer . pretty_string_literal ( ext ) ) ,
2032
2082
"]" ,
2033
2083
) ,
2034
2084
] )
@@ -2038,9 +2088,9 @@ impl Print for spv::ModuleDebugInfo {
2038
2088
printer. pretty_named_argument_prefix ( "module_processes" ) ,
2039
2089
pretty:: join_comma_sep (
2040
2090
"[" ,
2041
- module_processes. iter ( ) . map ( |proc| {
2042
- printer . string_literal_style ( ) . apply ( format ! ( "{proc:?}" ) )
2043
- } ) ,
2091
+ module_processes
2092
+ . iter ( )
2093
+ . map ( |proc| printer . pretty_string_literal ( proc ) ) ,
2044
2094
"]" ,
2045
2095
) ,
2046
2096
] )
@@ -2058,10 +2108,7 @@ impl Print for ExportKey {
2058
2108
type Output = pretty:: Fragment ;
2059
2109
fn print ( & self , printer : & Printer < ' _ > ) -> pretty:: Fragment {
2060
2110
match self {
2061
- & Self :: LinkName ( name) => printer
2062
- . string_literal_style ( )
2063
- . apply ( format ! ( "{:?}" , & printer. cx[ name] ) )
2064
- . into ( ) ,
2111
+ & Self :: LinkName ( name) => printer. pretty_string_literal ( & printer. cx [ name] ) ,
2065
2112
2066
2113
// HACK(eddyb) `interface_global_vars` should be recomputed by
2067
2114
// `spv::lift` anyway, so hiding them here mimics that.
@@ -2645,10 +2692,7 @@ impl Print for ConstDef {
2645
2692
ConstCtor :: SpvStringLiteralForExtInst ( s) => pretty:: Fragment :: new ( [
2646
2693
printer. pretty_spv_opcode ( printer. spv_op_style ( ) , wk. OpString ) ,
2647
2694
"(" . into ( ) ,
2648
- printer
2649
- . string_literal_style ( )
2650
- . apply ( format ! ( "{:?}" , & printer. cx[ s] ) )
2651
- . into ( ) ,
2695
+ printer. pretty_string_literal ( & printer. cx [ s] ) ,
2652
2696
")" . into ( ) ,
2653
2697
] ) ,
2654
2698
} ) ,
@@ -2661,11 +2705,9 @@ impl Print for Import {
2661
2705
fn print ( & self , printer : & Printer < ' _ > ) -> pretty:: Fragment {
2662
2706
match self {
2663
2707
& Self :: LinkName ( name) => pretty:: Fragment :: new ( [
2664
- printer. declarative_keyword_style ( ) . apply ( "import" ) ,
2708
+ printer. declarative_keyword_style ( ) . apply ( "import" ) . into ( ) ,
2665
2709
" " . into ( ) ,
2666
- printer
2667
- . string_literal_style ( )
2668
- . apply ( format ! ( "{:?}" , & printer. cx[ name] ) ) ,
2710
+ printer. pretty_string_literal ( & printer. cx [ name] ) ,
2669
2711
] ) ,
2670
2712
}
2671
2713
}
@@ -3379,10 +3421,7 @@ impl Print for DataInstDef {
3379
3421
printer
3380
3422
. pretty_spv_opcode ( printer. spv_op_style ( ) , wk. OpExtInstImport ) ,
3381
3423
"(" . into ( ) ,
3382
- printer
3383
- . string_literal_style ( )
3384
- . apply ( format ! ( "{:?}" , & printer. cx[ ext_set] ) )
3385
- . into ( ) ,
3424
+ printer. pretty_string_literal ( & printer. cx [ ext_set] ) ,
3386
3425
")" . into ( ) ,
3387
3426
] ) ,
3388
3427
printer
0 commit comments