@@ -313,82 +313,169 @@ impl SourceMapExtension for SourceMap {
313313 }
314314}
315315
316- fn map_path_prefix ( mapping : & FilePathMapping , path : & str ) -> String {
316+ // Takes a unix-style path and returns a platform specific path.
317+ fn path ( p : & str ) -> PathBuf {
318+ path_str ( p) . into ( )
319+ }
320+
321+ // Takes a unix-style path and returns a platform specific path.
322+ fn path_str ( p : & str ) -> String {
323+ #[ cfg( not( windows) ) ]
324+ {
325+ return p. into ( ) ;
326+ }
327+
328+ #[ cfg( windows) ]
329+ {
330+ let mut path = p. replace ( '/' , "\\ " ) ;
331+ if let Some ( rest) = path. strip_prefix ( '\\' ) {
332+ path = [ "X:\\ " , rest] . concat ( ) ;
333+ }
334+
335+ path
336+ }
337+ }
338+
339+ fn map_path_prefix ( mapping : & FilePathMapping , p : & str ) -> String {
317340 // It's important that we convert to a string here because that's what
318341 // later stages do too (e.g. in the backend), and comparing `Path` values
319342 // won't catch some differences at the string level, e.g. "abc" and "abc/"
320343 // compare as equal.
321- mapping. map_prefix ( path. into ( ) ) . 0 . to_string_lossy ( ) . to_string ( )
344+ mapping. map_prefix ( path ( p ) ) . 0 . to_string_lossy ( ) . to_string ( )
322345}
323346
324- #[ cfg( unix) ]
325347#[ test]
326348fn path_prefix_remapping ( ) {
327349 // Relative to relative
328350 {
329- let mapping = & FilePathMapping :: new ( vec ! [ ( "abc/def" . into ( ) , "foo" . into ( ) ) ] ) ;
351+ let mapping = & FilePathMapping :: new ( vec ! [ ( path ( "abc/def" ) , path ( "foo" ) ) ] ) ;
330352
331- assert_eq ! ( map_path_prefix( mapping, "abc/def/src/main.rs" ) , "foo/src/main.rs" ) ;
332- assert_eq ! ( map_path_prefix( mapping, "abc/def" ) , "foo" ) ;
353+ assert_eq ! ( map_path_prefix( mapping, "abc/def/src/main.rs" ) , path_str ( "foo/src/main.rs" ) ) ;
354+ assert_eq ! ( map_path_prefix( mapping, "abc/def" ) , path_str ( "foo" ) ) ;
333355 }
334356
335357 // Relative to absolute
336358 {
337- let mapping = & FilePathMapping :: new ( vec ! [ ( "abc/def" . into ( ) , "/foo" . into ( ) ) ] ) ;
359+ let mapping = & FilePathMapping :: new ( vec ! [ ( path ( "abc/def" ) , path ( "/foo" ) ) ] ) ;
338360
339- assert_eq ! ( map_path_prefix( mapping, "abc/def/src/main.rs" ) , "/foo/src/main.rs" ) ;
340- assert_eq ! ( map_path_prefix( mapping, "abc/def" ) , "/foo" ) ;
361+ assert_eq ! ( map_path_prefix( mapping, "abc/def/src/main.rs" ) , path_str ( "/foo/src/main.rs" ) ) ;
362+ assert_eq ! ( map_path_prefix( mapping, "abc/def" ) , path_str ( "/foo" ) ) ;
341363 }
342364
343365 // Absolute to relative
344366 {
345- let mapping = & FilePathMapping :: new ( vec ! [ ( "/abc/def" . into ( ) , "foo" . into ( ) ) ] ) ;
367+ let mapping = & FilePathMapping :: new ( vec ! [ ( path ( "/abc/def" ) , path ( "foo" ) ) ] ) ;
346368
347- assert_eq ! ( map_path_prefix( mapping, "/abc/def/src/main.rs" ) , "foo/src/main.rs" ) ;
348- assert_eq ! ( map_path_prefix( mapping, "/abc/def" ) , "foo" ) ;
369+ assert_eq ! ( map_path_prefix( mapping, "/abc/def/src/main.rs" ) , path_str ( "foo/src/main.rs" ) ) ;
370+ assert_eq ! ( map_path_prefix( mapping, "/abc/def" ) , path_str ( "foo" ) ) ;
349371 }
350372
351373 // Absolute to absolute
352374 {
353- let mapping = & FilePathMapping :: new ( vec ! [ ( "/abc/def" . into ( ) , "/foo" . into ( ) ) ] ) ;
375+ let mapping = & FilePathMapping :: new ( vec ! [ ( path ( "/abc/def" ) , path ( "/foo" ) ) ] ) ;
354376
355- assert_eq ! ( map_path_prefix( mapping, "/abc/def/src/main.rs" ) , "/foo/src/main.rs" ) ;
356- assert_eq ! ( map_path_prefix( mapping, "/abc/def" ) , "/foo" ) ;
377+ assert_eq ! ( map_path_prefix( mapping, "/abc/def/src/main.rs" ) , path_str ( "/foo/src/main.rs" ) ) ;
378+ assert_eq ! ( map_path_prefix( mapping, "/abc/def" ) , path_str ( "/foo" ) ) ;
357379 }
358380}
359381
360- #[ cfg( windows) ]
361382#[ test]
362- fn path_prefix_remapping_from_relative2 ( ) {
363- // Relative to relative
364- {
365- let mapping = & FilePathMapping :: new ( vec ! [ ( "abc\\ def" . into( ) , "foo" . into( ) ) ] ) ;
383+ fn path_prefix_remapping_expand_to_absolute ( ) {
384+ // "virtual" working directory is relative path
385+ let mapping =
386+ & FilePathMapping :: new ( vec ! [ ( path( "/foo" ) , path( "FOO" ) ) , ( path( "/bar" ) , path( "BAR" ) ) ] ) ;
387+ let working_directory = path ( "/foo" ) ;
388+ let working_directory = RealFileName :: Remapped {
389+ local_path : Some ( working_directory. clone ( ) ) ,
390+ virtual_name : mapping. map_prefix ( working_directory) . 0 ,
391+ } ;
392+
393+ assert_eq ! ( working_directory. remapped_path_if_available( ) , path( "FOO" ) ) ;
394+
395+ // Unmapped absolute path
396+ assert_eq ! (
397+ mapping. to_embeddable_absolute_path(
398+ RealFileName :: LocalPath ( path( "/foo/src/main.rs" ) ) ,
399+ & working_directory
400+ ) ,
401+ RealFileName :: Remapped { local_path: None , virtual_name: path( "FOO/src/main.rs" ) }
402+ ) ;
366403
367- assert_eq ! ( map_path_prefix( mapping, "abc\\ def\\ src\\ main.rs" ) , "foo\\ src\\ main.rs" ) ;
368- assert_eq ! ( map_path_prefix( mapping, "abc\\ def" ) , "foo" ) ;
369- }
404+ // Unmapped absolute path with unrelated working directory
405+ assert_eq ! (
406+ mapping. to_embeddable_absolute_path(
407+ RealFileName :: LocalPath ( path( "/bar/src/main.rs" ) ) ,
408+ & working_directory
409+ ) ,
410+ RealFileName :: Remapped { local_path: None , virtual_name: path( "BAR/src/main.rs" ) }
411+ ) ;
370412
371- // Relative to absolute
372- {
373- let mapping = & FilePathMapping :: new ( vec ! [ ( "abc\\ def" . into( ) , "X:\\ foo" . into( ) ) ] ) ;
413+ // Unmapped absolute path that does not match any prefix
414+ assert_eq ! (
415+ mapping. to_embeddable_absolute_path(
416+ RealFileName :: LocalPath ( path( "/quux/src/main.rs" ) ) ,
417+ & working_directory
418+ ) ,
419+ RealFileName :: LocalPath ( path( "/quux/src/main.rs" ) ) ,
420+ ) ;
374421
375- assert_eq ! ( map_path_prefix( mapping, "abc\\ def\\ src\\ main.rs" ) , "X:\\ foo\\ src\\ main.rs" ) ;
376- assert_eq ! ( map_path_prefix( mapping, "abc\\ def" ) , "X:\\ foo" ) ;
377- }
422+ // Unmapped relative path
423+ assert_eq ! (
424+ mapping. to_embeddable_absolute_path(
425+ RealFileName :: LocalPath ( path( "src/main.rs" ) ) ,
426+ & working_directory
427+ ) ,
428+ RealFileName :: Remapped { local_path: None , virtual_name: path( "FOO/src/main.rs" ) }
429+ ) ;
378430
379- // Absolute to relative
380- {
381- let mapping = & FilePathMapping :: new ( vec ! [ ( "X:\\ abc\\ def" . into( ) , "foo" . into( ) ) ] ) ;
431+ // Unmapped relative path with `./`
432+ assert_eq ! (
433+ mapping. to_embeddable_absolute_path(
434+ RealFileName :: LocalPath ( path( "./src/main.rs" ) ) ,
435+ & working_directory
436+ ) ,
437+ RealFileName :: Remapped { local_path: None , virtual_name: path( "FOO/src/main.rs" ) }
438+ ) ;
382439
383- assert_eq ! ( map_path_prefix( mapping, "X:\\ abc\\ def\\ src\\ main.rs" ) , "foo\\ src\\ main.rs" ) ;
384- assert_eq ! ( map_path_prefix( mapping, "X:\\ abc\\ def" ) , "foo" ) ;
385- }
440+ // Unmapped relative path that does not match any prefix
441+ assert_eq ! (
442+ mapping. to_embeddable_absolute_path(
443+ RealFileName :: LocalPath ( path( "quux/src/main.rs" ) ) ,
444+ & RealFileName :: LocalPath ( path( "/abc" ) ) ,
445+ ) ,
446+ RealFileName :: LocalPath ( path( "/abc/quux/src/main.rs" ) ) ,
447+ ) ;
386448
387- // Absolute to absolute
388- {
389- let mapping = & FilePathMapping :: new ( vec ! [ ( "X:\\ abc\\ def" . into( ) , "X:\\ foo" . into( ) ) ] ) ;
449+ // Already remapped absolute path
450+ assert_eq ! (
451+ mapping. to_embeddable_absolute_path(
452+ RealFileName :: Remapped {
453+ local_path: Some ( path( "/foo/src/main.rs" ) ) ,
454+ virtual_name: path( "FOO/src/main.rs" ) ,
455+ } ,
456+ & working_directory
457+ ) ,
458+ RealFileName :: Remapped { local_path: None , virtual_name: path( "FOO/src/main.rs" ) }
459+ ) ;
390460
391- assert_eq ! ( map_path_prefix( mapping, "X:\\ abc\\ def\\ src\\ main.rs" ) , "X:\\ foo\\ src\\ main.rs" ) ;
392- assert_eq ! ( map_path_prefix( mapping, "X:\\ abc\\ def" ) , "X:\\ foo" ) ;
393- }
461+ // Already remapped absolute path, with unrelated working directory
462+ assert_eq ! (
463+ mapping. to_embeddable_absolute_path(
464+ RealFileName :: Remapped {
465+ local_path: Some ( path( "/bar/src/main.rs" ) ) ,
466+ virtual_name: path( "BAR/src/main.rs" ) ,
467+ } ,
468+ & working_directory
469+ ) ,
470+ RealFileName :: Remapped { local_path: None , virtual_name: path( "BAR/src/main.rs" ) }
471+ ) ;
472+
473+ // Already remapped relative path
474+ assert_eq ! (
475+ mapping. to_embeddable_absolute_path(
476+ RealFileName :: Remapped { local_path: None , virtual_name: path( "XYZ/src/main.rs" ) } ,
477+ & working_directory
478+ ) ,
479+ RealFileName :: Remapped { local_path: None , virtual_name: path( "XYZ/src/main.rs" ) }
480+ ) ;
394481}
0 commit comments