@@ -544,13 +544,74 @@ namespace A {
544
544
return a1.x + 10;|]
545
545
}
546
546
}
547
+ }` ) ;
548
+ // The "b" type parameters aren't used and shouldn't be passed to the extracted function.
549
+ // Type parameters should be in syntactic order (i.e. in order or character offset from BOF).
550
+ // In all cases, we could use type inference, rather than passing explicit type arguments.
551
+ // Note the inclusion of arrow functions to ensure that some type parameters are not from
552
+ // targetable scopes.
553
+ testExtractMethod ( "extractMethod13" ,
554
+ `<U1a, U1b>(u1a: U1a, u1b: U1b) => {
555
+ function F1<T1a, T1b>(t1a: T1a, t1b: T1b) {
556
+ <U2a, U2b>(u2a: U2a, u2b: U2b) => {
557
+ function F2<T2a, T2b>(t2a: T2a, t2b: T2b) {
558
+ <U3a, U3b>(u3a: U3a, u3b: U3b) => {
559
+ [#|t1a.toString();
560
+ t2a.toString();
561
+ u1a.toString();
562
+ u2a.toString();
563
+ u3a.toString();|]
564
+ }
565
+ }
566
+ }
567
+ }
568
+ }` ) ;
569
+ // This test is descriptive, rather than normative. The current implementation
570
+ // doesn't handle type parameter shadowing.
571
+ testExtractMethod ( "extractMethod14" ,
572
+ `function F<T>(t1: T) {
573
+ function F<T>(t2: T) {
574
+ [#|t1.toString();
575
+ t2.toString();|]
576
+ }
577
+ }` ) ;
578
+ // Confirm that the constraint is preserved.
579
+ testExtractMethod ( "extractMethod15" ,
580
+ `function F<T>(t1: T) {
581
+ function F<U extends T[]>(t2: U) {
582
+ [#|t2.toString();|]
583
+ }
584
+ }` ) ;
585
+ // Confirm that the contextual type of an extracted expression counts as a use.
586
+ testExtractMethod ( "extractMethod16" ,
587
+ `function F<T>() {
588
+ const array: T[] = [#|[]|];
589
+ }` ) ;
590
+ // Class type parameter
591
+ testExtractMethod ( "extractMethod17" ,
592
+ `class C<T1, T2> {
593
+ M(t1: T1, t2: T2) {
594
+ [#|t1.toString()|];
595
+ }
596
+ }` ) ;
597
+ // Method type parameter
598
+ testExtractMethod ( "extractMethod18" ,
599
+ `class C {
600
+ M<T1, T2>(t1: T1, t2: T2) {
601
+ [#|t1.toString()|];
602
+ }
603
+ }` ) ;
604
+ // Coupled constraints
605
+ testExtractMethod ( "extractMethod19" ,
606
+ `function F<T, U extends T[], V extends U[]>(v: V) {
607
+ [#|v.toString()|];
547
608
}` ) ;
548
609
} ) ;
549
610
550
611
551
612
function testExtractMethod ( caption : string , text : string ) {
552
613
it ( caption , ( ) => {
553
- Harness . Baseline . runBaseline ( `extractMethod/${ caption } .js ` , ( ) => {
614
+ Harness . Baseline . runBaseline ( `extractMethod/${ caption } .ts ` , ( ) => {
554
615
const t = extractTest ( text ) ;
555
616
const selectionRange = t . ranges . get ( "selection" ) ;
556
617
if ( ! selectionRange ) {
@@ -560,7 +621,7 @@ namespace A {
560
621
path : "/a.ts" ,
561
622
content : t . source
562
623
} ;
563
- const host = projectSystem . createServerHost ( [ f ] ) ;
624
+ const host = projectSystem . createServerHost ( [ f , projectSystem . libFile ] ) ;
564
625
const projectService = projectSystem . createProjectService ( host ) ;
565
626
projectService . openClientFile ( f . path ) ;
566
627
const program = projectService . inferredProjects [ 0 ] . getLanguageService ( ) . getProgram ( ) ;
@@ -577,11 +638,11 @@ namespace A {
577
638
assert . equal ( result . errors , undefined , "expect no errors" ) ;
578
639
const results = refactor . extractMethod . getPossibleExtractions ( result . targetRange , context ) ;
579
640
const data : string [ ] = [ ] ;
580
- data . push ( `==ORIGINAL==` ) ;
641
+ data . push ( `// ==ORIGINAL==` ) ;
581
642
data . push ( sourceFile . text ) ;
582
643
for ( const r of results ) {
583
644
const changes = refactor . extractMethod . getPossibleExtractions ( result . targetRange , context , results . indexOf ( r ) ) [ 0 ] . changes ;
584
- data . push ( `==SCOPE::${ r . scopeDescription } ==` ) ;
645
+ data . push ( `// ==SCOPE::${ r . scopeDescription } ==` ) ;
585
646
data . push ( textChanges . applyChanges ( sourceFile . text , changes [ 0 ] . textChanges ) ) ;
586
647
}
587
648
return data . join ( newLineCharacter ) ;
0 commit comments