@@ -831,5 +831,158 @@ module m3 { }\
831
831
const index = source . indexOf ( "enum " ) + "enum " . length ;
832
832
insertCode ( source , index , "Fo" ) ;
833
833
} ) ;
834
+
835
+ describe ( "comment directives" , ( ) => {
836
+ const tsIgnoreComment = "// @ts-ignore" ;
837
+ const textWithIgnoreComment = `const x = 10;
838
+ function foo() {
839
+ // @ts-ignore
840
+ let y: string = x;
841
+ return y;
842
+ }
843
+ function bar() {
844
+ // @ts-ignore
845
+ let z : string = x;
846
+ return z;
847
+ }
848
+ function bar3() {
849
+ // @ts-ignore
850
+ let z : string = x;
851
+ return z;
852
+ }
853
+ foo();
854
+ bar();
855
+ bar3();` ;
856
+ verifyScenario ( "when deleting ts-ignore comment" , verifyDelete ) ;
857
+ verifyScenario ( "when inserting ts-ignore comment" , verifyInsert ) ;
858
+ verifyScenario ( "when changing ts-ignore comment to blah" , verifyChangeToBlah ) ;
859
+ verifyScenario ( "when changing blah comment to ts-ignore" , verifyChangeBackToDirective ) ;
860
+ verifyScenario ( "when deleting blah comment" , verifyDeletingBlah ) ;
861
+ verifyScenario ( "when changing text that adds another comment" , verifyChangeDirectiveType ) ;
862
+ verifyScenario ( "when changing text that keeps the comment but adds more nodes" , verifyReuseChange ) ;
863
+
864
+ function verifyCommentDirectives ( oldText : IScriptSnapshot , newTextAndChange : { text : IScriptSnapshot ; textChangeRange : TextChangeRange ; } ) {
865
+ const { incrementalNewTree, newTree } = compareTrees ( oldText , newTextAndChange . text , newTextAndChange . textChangeRange , - 1 ) ;
866
+ assert . deepEqual ( incrementalNewTree . commentDirectives , newTree . commentDirectives ) ;
867
+ }
868
+
869
+ function verifyScenario ( scenario : string , verifyChange : ( atIndex : number , singleIgnore ?: true ) => void ) {
870
+ it ( `${ scenario } - 0` , ( ) => {
871
+ verifyChange ( 0 ) ;
872
+ } ) ;
873
+ it ( `${ scenario } - 1` , ( ) => {
874
+ verifyChange ( 1 ) ;
875
+ } ) ;
876
+ it ( `${ scenario } - 2` , ( ) => {
877
+ verifyChange ( 2 ) ;
878
+ } ) ;
879
+ it ( `${ scenario } - with single ts-ignore` , ( ) => {
880
+ verifyChange ( 0 , /*singleIgnore*/ true ) ;
881
+ } ) ;
882
+ }
883
+
884
+ function getIndexOfTsIgnoreComment ( atIndex : number ) {
885
+ let index : number ;
886
+ for ( let i = 0 ; i <= atIndex ; i ++ ) {
887
+ index = textWithIgnoreComment . indexOf ( tsIgnoreComment ) ;
888
+ }
889
+ return index ! ;
890
+ }
891
+
892
+ function textWithIgnoreCommentFrom ( text : string , singleIgnore : true | undefined ) {
893
+ if ( ! singleIgnore ) return text ;
894
+ const splits = text . split ( tsIgnoreComment ) ;
895
+ if ( splits . length > 2 ) {
896
+ const tail = splits [ splits . length - 2 ] + splits [ splits . length - 1 ] ;
897
+ splits . length = splits . length - 2 ;
898
+ return splits . join ( tsIgnoreComment ) + tail ;
899
+ }
900
+ else {
901
+ return splits . join ( tsIgnoreComment ) ;
902
+ }
903
+ }
904
+
905
+ function verifyDelete ( atIndex : number , singleIgnore ?: true ) {
906
+ const index = getIndexOfTsIgnoreComment ( atIndex ) ;
907
+ const oldText = ScriptSnapshot . fromString ( textWithIgnoreCommentFrom ( textWithIgnoreComment , singleIgnore ) ) ;
908
+ const newTextAndChange = withDelete ( oldText , index , tsIgnoreComment . length ) ;
909
+ verifyCommentDirectives ( oldText , newTextAndChange ) ;
910
+ }
911
+
912
+ function verifyInsert ( atIndex : number , singleIgnore ?: true ) {
913
+ const index = getIndexOfTsIgnoreComment ( atIndex ) ;
914
+ const source = textWithIgnoreCommentFrom ( textWithIgnoreComment . slice ( 0 , index ) + textWithIgnoreComment . slice ( index + tsIgnoreComment . length ) , singleIgnore ) ;
915
+ const oldText = ScriptSnapshot . fromString ( source ) ;
916
+ const newTextAndChange = withInsert ( oldText , index , tsIgnoreComment ) ;
917
+ verifyCommentDirectives ( oldText , newTextAndChange ) ;
918
+ }
919
+
920
+ function verifyChangeToBlah ( atIndex : number , singleIgnore ?: true ) {
921
+ const index = getIndexOfTsIgnoreComment ( atIndex ) + "// " . length ;
922
+ const oldText = ScriptSnapshot . fromString ( textWithIgnoreCommentFrom ( textWithIgnoreComment , singleIgnore ) ) ;
923
+ const newTextAndChange = withChange ( oldText , index , 1 , "blah " ) ;
924
+ verifyCommentDirectives ( oldText , newTextAndChange ) ;
925
+ }
926
+
927
+ function verifyChangeBackToDirective ( atIndex : number , singleIgnore ?: true ) {
928
+ const index = getIndexOfTsIgnoreComment ( atIndex ) + "// " . length ;
929
+ const source = textWithIgnoreCommentFrom ( textWithIgnoreComment . slice ( 0 , index ) + "blah " + textWithIgnoreComment . slice ( index + 1 ) , singleIgnore ) ;
930
+ const oldText = ScriptSnapshot . fromString ( source ) ;
931
+ const newTextAndChange = withChange ( oldText , index , "blah " . length , "@" ) ;
932
+ verifyCommentDirectives ( oldText , newTextAndChange ) ;
933
+ }
934
+
935
+ function verifyDeletingBlah ( atIndex : number , singleIgnore ?: true ) {
936
+ const tsIgnoreIndex = getIndexOfTsIgnoreComment ( atIndex ) ;
937
+ const index = tsIgnoreIndex + "// " . length ;
938
+ const source = textWithIgnoreCommentFrom ( textWithIgnoreComment . slice ( 0 , index ) + "blah " + textWithIgnoreComment . slice ( index + 1 ) , singleIgnore ) ;
939
+ const oldText = ScriptSnapshot . fromString ( source ) ;
940
+ const newTextAndChange = withDelete ( oldText , tsIgnoreIndex , tsIgnoreComment . length + "blah" . length ) ;
941
+ verifyCommentDirectives ( oldText , newTextAndChange ) ;
942
+ }
943
+
944
+ function verifyChangeDirectiveType ( atIndex : number , singleIgnore ?: true ) {
945
+ const index = getIndexOfTsIgnoreComment ( atIndex ) + "// @ts-" . length ;
946
+ const oldText = ScriptSnapshot . fromString ( textWithIgnoreCommentFrom ( textWithIgnoreComment , singleIgnore ) ) ;
947
+ const newTextAndChange = withChange ( oldText , index , "ignore" . length , "expect-error" ) ;
948
+ verifyCommentDirectives ( oldText , newTextAndChange ) ;
949
+ }
950
+
951
+ function verifyReuseChange ( atIndex : number , singleIgnore ?: true ) {
952
+ const source = `const x = 10;
953
+ function foo1() {
954
+ const x1 = 10;
955
+ // @ts-ignore
956
+ let y0: string = x;
957
+ let y1: string = x;
958
+ return y1;
959
+ }
960
+ function foo2() {
961
+ const x2 = 10;
962
+ // @ts-ignore
963
+ let y0: string = x;
964
+ let y2: string = x;
965
+ return y2;
966
+ }
967
+ function foo3() {
968
+ const x3 = 10;
969
+ // @ts-ignore
970
+ let y0: string = x;
971
+ let y3: string = x;
972
+ return y3;
973
+ }
974
+ foo1();
975
+ foo2();
976
+ foo3();` ;
977
+ const oldText = ScriptSnapshot . fromString ( textWithIgnoreCommentFrom ( source , singleIgnore ) ) ;
978
+ const start = source . indexOf ( `const x${ atIndex + 1 } ` ) ;
979
+ const letStr = `let y${ atIndex + 1 } : string = x;` ;
980
+ const end = source . indexOf ( letStr ) + letStr . length ;
981
+ const oldSubStr = source . slice ( start , end ) ;
982
+ const newText = oldSubStr . replace ( letStr , `let yn : string = x;` ) ;
983
+ const newTextAndChange = withChange ( oldText , start , end - start , newText ) ;
984
+ verifyCommentDirectives ( oldText , newTextAndChange ) ;
985
+ }
986
+ } ) ;
834
987
} ) ;
835
988
}
0 commit comments