@@ -855,21 +855,31 @@ namespace Harness {
855
855
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
856
856
const getCanonicalFileName = ts . createGetCanonicalFileName ( useCaseSensitiveFileNames ) ;
857
857
858
- const fileMap : ts . FileMap < ts . SourceFile > = ts . createFileMap < ts . SourceFile > ( ) ;
858
+ let realPathMap : ts . FileMap < string > ;
859
+ const fileMap : ts . FileMap < ( ) => ts . SourceFile > = ts . createFileMap < ( ) => ts . SourceFile > ( ) ;
859
860
for ( const file of inputFiles ) {
860
861
if ( file . content !== undefined ) {
861
862
const fileName = ts . normalizePath ( file . unitName ) ;
862
- const sourceFile = createSourceFileAndAssertInvariants ( fileName , file . content , scriptTarget ) ;
863
863
const path = ts . toPath ( file . unitName , currentDirectory , getCanonicalFileName ) ;
864
- fileMap . set ( path , sourceFile ) ;
864
+ if ( file . fileOptions && file . fileOptions [ "symlink" ] ) {
865
+ const link = file . fileOptions [ "symlink" ] ;
866
+ const linkPath = ts . toPath ( link , currentDirectory , getCanonicalFileName ) ;
867
+ if ( ! realPathMap ) {
868
+ realPathMap = ts . createFileMap < string > ( ) ;
869
+ }
870
+ realPathMap . set ( linkPath , fileName ) ;
871
+ fileMap . set ( path , ( ) : ts . SourceFile => { throw new Error ( "Symlinks should always be resolved to a realpath first" ) ; } ) ;
872
+ }
873
+ const sourceFile = createSourceFileAndAssertInvariants ( fileName , file . content , scriptTarget ) ;
874
+ fileMap . set ( path , ( ) => sourceFile ) ;
865
875
}
866
876
}
867
877
868
878
function getSourceFile ( fileName : string , languageVersion : ts . ScriptTarget ) {
869
879
fileName = ts . normalizePath ( fileName ) ;
870
880
const path = ts . toPath ( fileName , currentDirectory , getCanonicalFileName ) ;
871
881
if ( fileMap . contains ( path ) ) {
872
- return fileMap . get ( path ) ;
882
+ return fileMap . get ( path ) ( ) ;
873
883
}
874
884
else if ( fileName === fourslashFileName ) {
875
885
const tsFn = "tests/cases/fourslash/" + fourslashFileName ;
@@ -898,11 +908,16 @@ namespace Harness {
898
908
useCaseSensitiveFileNames : ( ) => useCaseSensitiveFileNames ,
899
909
getNewLine : ( ) => newLine ,
900
910
fileExists : fileName => {
901
- return fileMap . contains ( ts . toPath ( fileName , currentDirectory , getCanonicalFileName ) ) ;
911
+ const path = ts . toPath ( fileName , currentDirectory , getCanonicalFileName ) ;
912
+ return fileMap . contains ( path ) || ( realPathMap && realPathMap . contains ( path ) ) ;
902
913
} ,
903
914
readFile : ( fileName : string ) : string => {
904
- return fileMap . get ( ts . toPath ( fileName , currentDirectory , getCanonicalFileName ) ) . getText ( ) ;
905
- }
915
+ return fileMap . get ( ts . toPath ( fileName , currentDirectory , getCanonicalFileName ) ) ( ) . getText ( ) ;
916
+ } ,
917
+ realpath : realPathMap && ( ( f : string ) => {
918
+ const path = ts . toPath ( f , currentDirectory , getCanonicalFileName ) ;
919
+ return realPathMap . contains ( path ) ? realPathMap . get ( path ) : path ;
920
+ } )
906
921
} ;
907
922
}
908
923
@@ -923,7 +938,8 @@ namespace Harness {
923
938
{ name : "libFiles" , type : "string" } ,
924
939
{ name : "noErrorTruncation" , type : "boolean" } ,
925
940
{ name : "suppressOutputPathCheck" , type : "boolean" } ,
926
- { name : "noImplicitReferences" , type : "boolean" }
941
+ { name : "noImplicitReferences" , type : "boolean" } ,
942
+ { name : "symlink" , type : "string" }
927
943
] ;
928
944
929
945
let optionsIndex : ts . Map < ts . CommandLineOption > ;
@@ -978,6 +994,7 @@ namespace Harness {
978
994
export interface TestFile {
979
995
unitName : string ;
980
996
content : string ;
997
+ fileOptions ?: any ;
981
998
}
982
999
983
1000
export interface CompilationOutput {
@@ -1415,10 +1432,8 @@ namespace Harness {
1415
1432
// Comment line, check for global/file @options and record them
1416
1433
optionRegex . lastIndex = 0 ;
1417
1434
const metaDataName = testMetaData [ 1 ] . toLowerCase ( ) ;
1418
- if ( metaDataName === "filename" ) {
1419
- currentFileOptions [ testMetaData [ 1 ] ] = testMetaData [ 2 ] ;
1420
- }
1421
- else {
1435
+ currentFileOptions [ testMetaData [ 1 ] ] = testMetaData [ 2 ] ;
1436
+ if ( metaDataName !== "filename" ) {
1422
1437
continue ;
1423
1438
}
1424
1439
0 commit comments