@@ -6925,7 +6925,7 @@ namespace ts {
6925
6925
6926
6926
export interface ObjectAllocator {
6927
6927
getNodeConstructor ( ) : new ( kind : SyntaxKind , pos ?: number , end ?: number ) => Node ;
6928
- getTokenConstructor ( ) : new < TKind extends SyntaxKind > ( kind : TKind , pos ?: number , end ?: number ) => Token < TKind > ;
6928
+ getTokenConstructor ( ) : { new < TKind extends SyntaxKind > ( kind : TKind , pos ?: number , end ?: number ) : Token < TKind > } ;
6929
6929
getIdentifierConstructor ( ) : new ( kind : SyntaxKind . Identifier , pos ?: number , end ?: number ) => Identifier ;
6930
6930
getSourceFileConstructor ( ) : new ( kind : SyntaxKind . SourceFile , pos ?: number , end ?: number ) => SourceFile ;
6931
6931
getSymbolConstructor ( ) : new ( flags : SymbolFlags , name : __String ) => Symbol ;
@@ -7687,16 +7687,38 @@ namespace ts {
7687
7687
return path ;
7688
7688
}
7689
7689
7690
+ // check path for these segments: '', '.'. '..'
7691
+ const relativePathSegmentRegExp = / ( ^ | \/ ) \. { 0 , 2 } ( $ | \/ ) / ;
7692
+
7690
7693
function comparePathsWorker ( a : string , b : string , componentComparer : ( a : string , b : string ) => Comparison ) {
7691
7694
if ( a === b ) return Comparison . EqualTo ;
7692
7695
if ( a === undefined ) return Comparison . LessThan ;
7693
7696
if ( b === undefined ) return Comparison . GreaterThan ;
7697
+
7698
+ // NOTE: Performance optimization - shortcut if the root segments differ as there would be no
7699
+ // need to perform path reduction.
7700
+ const aRoot = a . substring ( 0 , getRootLength ( a ) ) ;
7701
+ const bRoot = b . substring ( 0 , getRootLength ( b ) ) ;
7702
+ const result = compareStringsCaseInsensitive ( aRoot , bRoot ) ;
7703
+ if ( result !== Comparison . EqualTo ) {
7704
+ return result ;
7705
+ }
7706
+
7707
+ // NOTE: Performance optimization - shortcut if there are no relative path segments in
7708
+ // the non-root portion of the path
7709
+ const aRest = a . substring ( aRoot . length ) ;
7710
+ const bRest = b . substring ( bRoot . length ) ;
7711
+ if ( ! relativePathSegmentRegExp . test ( aRest ) && ! relativePathSegmentRegExp . test ( bRest ) ) {
7712
+ return componentComparer ( aRest , bRest ) ;
7713
+ }
7714
+
7715
+ // The path contains a relative path segment. Normalize the paths and perform a slower component
7716
+ // by component comparison.
7694
7717
const aComponents = reducePathComponents ( getPathComponents ( a ) ) ;
7695
7718
const bComponents = reducePathComponents ( getPathComponents ( b ) ) ;
7696
7719
const sharedLength = Math . min ( aComponents . length , bComponents . length ) ;
7697
- for ( let i = 0 ; i < sharedLength ; i ++ ) {
7698
- const stringComparer = i === 0 ? compareStringsCaseInsensitive : componentComparer ;
7699
- const result = stringComparer ( aComponents [ i ] , bComponents [ i ] ) ;
7720
+ for ( let i = 1 ; i < sharedLength ; i ++ ) {
7721
+ const result = componentComparer ( aComponents [ i ] , bComponents [ i ] ) ;
7700
7722
if ( result !== Comparison . EqualTo ) {
7701
7723
return result ;
7702
7724
}
0 commit comments