@@ -144,16 +144,30 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined {
144
144
}
145
145
const namespace = callExpression . expression . expression ;
146
146
const func = callExpression . expression . name ;
147
- if ( ! ts . isIdentifier ( namespace ) || ! ts . isIdentifier ( func ) ) {
147
+ if ( ! ( ts . isIdentifier ( namespace ) || namespace . getText ( ) === "verify.not" ) || ! ts . isIdentifier ( func ) ) {
148
148
console . error ( `Expected identifiers for namespace and function, got ${ namespace . getText ( ) } and ${ func . getText ( ) } ` ) ;
149
149
return undefined ;
150
150
}
151
+ if ( ! ts . isIdentifier ( namespace ) ) {
152
+ switch ( func . text ) {
153
+ case "quickInfoExists" :
154
+ return parseQuickInfoArgs ( "notQuickInfoExists" , callExpression . arguments ) ;
155
+ }
156
+ console . error ( `Unrecognized fourslash statement: ${ statement . getText ( ) } ` ) ;
157
+ return undefined ;
158
+ }
151
159
// `verify.(...)`
152
160
if ( namespace . text === "verify" ) {
153
161
switch ( func . text ) {
154
162
case "completions" :
155
163
// `verify.completions(...)`
156
164
return parseVerifyCompletionsArgs ( callExpression . arguments ) ;
165
+ case "quickInfoAt" :
166
+ case "quickInfoExists" :
167
+ case "quickInfoIs" :
168
+ case "quickInfos" :
169
+ // `verify.quickInfo...(...)`
170
+ return parseQuickInfoArgs ( func . text , callExpression . arguments ) ;
157
171
case "baselineFindAllReferences" :
158
172
// `verify.baselineFindAllReferences(...)`
159
173
return [ parseBaselineFindAllReferencesArgs ( callExpression . arguments ) ] ;
@@ -721,6 +735,127 @@ function parseBaselineQuickInfo(args: ts.NodeArray<ts.Expression>): Cmd {
721
735
} ;
722
736
}
723
737
738
+ function parseQuickInfoArgs ( funcName : string , args : readonly ts . Expression [ ] ) : VerifyQuickInfoCmd [ ] | undefined {
739
+ // We currently don't support 'expectedTags'.
740
+ switch ( funcName ) {
741
+ case "quickInfoAt" : {
742
+ if ( args . length < 1 || args . length > 3 ) {
743
+ console . error ( `Expected 1 or 2 arguments in quickInfoIs, got ${ args . map ( arg => arg . getText ( ) ) . join ( ", " ) } ` ) ;
744
+ return undefined ;
745
+ }
746
+ if ( ! ts . isStringLiteralLike ( args [ 0 ] ) ) {
747
+ console . error ( `Expected string literal for first argument in quickInfoAt, got ${ args [ 0 ] . getText ( ) } ` ) ;
748
+ return undefined ;
749
+ }
750
+ const marker = getGoStringLiteral ( args [ 0 ] . text ) ;
751
+ let text : string | undefined ;
752
+ if ( args [ 1 ] ) {
753
+ if ( ! ts . isStringLiteralLike ( args [ 1 ] ) ) {
754
+ console . error ( `Expected string literal for second argument in quickInfoAt, got ${ args [ 1 ] . getText ( ) } ` ) ;
755
+ return undefined ;
756
+ }
757
+ text = getGoStringLiteral ( args [ 1 ] . text ) ;
758
+ }
759
+ let docs : string | undefined ;
760
+ if ( args [ 2 ] ) {
761
+ if ( ! ts . isStringLiteralLike ( args [ 2 ] ) && args [ 2 ] . getText ( ) !== "undefined" ) {
762
+ console . error ( `Expected string literal or undefined for third argument in quickInfoAt, got ${ args [ 2 ] . getText ( ) } ` ) ;
763
+ return undefined ;
764
+ }
765
+ if ( ts . isStringLiteralLike ( args [ 2 ] ) ) {
766
+ docs = getGoStringLiteral ( args [ 1 ] . text ) ;
767
+ }
768
+ }
769
+ return [ {
770
+ kind : "quickInfoAt" ,
771
+ marker,
772
+ text,
773
+ docs,
774
+ } ] ;
775
+ }
776
+ case "quickInfos" : {
777
+ const cmds : VerifyQuickInfoCmd [ ] = [ ] ;
778
+ if ( args . length !== 1 || ! ts . isObjectLiteralExpression ( args [ 0 ] ) ) {
779
+ console . error ( `Expected a single object literal argument in quickInfos, got ${ args . map ( arg => arg . getText ( ) ) . join ( ", " ) } ` ) ;
780
+ return undefined ;
781
+ }
782
+ for ( const prop of args [ 0 ] . properties ) {
783
+ if ( ! ts . isPropertyAssignment ( prop ) ) {
784
+ console . error ( `Expected property assignment in quickInfos, got ${ prop . getText ( ) } ` ) ;
785
+ return undefined ;
786
+ }
787
+ if ( ! ( ts . isIdentifier ( prop . name ) || ts . isStringLiteralLike ( prop . name ) || ts . isNumericLiteral ( prop . name ) ) ) {
788
+ console . error ( `Expected identifier or literal for property name in quickInfos, got ${ prop . name . getText ( ) } ` ) ;
789
+ return undefined ;
790
+ }
791
+ const marker = getGoStringLiteral ( prop . name . text ) ;
792
+ let text : string | undefined ;
793
+ let docs : string | undefined ;
794
+ if ( ts . isArrayLiteralExpression ( prop . initializer ) ) {
795
+ if ( prop . initializer . elements . length !== 2 ) {
796
+ console . error ( `Expected two elements in array literal for quickInfos property, got ${ prop . initializer . getText ( ) } ` ) ;
797
+ return undefined ;
798
+ }
799
+ if ( ! ts . isStringLiteralLike ( prop . initializer . elements [ 0 ] ) || ! ts . isStringLiteralLike ( prop . initializer . elements [ 1 ] ) ) {
800
+ console . error ( `Expected string literals in array literal for quickInfos property, got ${ prop . initializer . getText ( ) } ` ) ;
801
+ return undefined ;
802
+ }
803
+ text = getGoStringLiteral ( prop . initializer . elements [ 0 ] . text ) ;
804
+ docs = getGoStringLiteral ( prop . initializer . elements [ 1 ] . text ) ;
805
+ }
806
+ else if ( ts . isStringLiteralLike ( prop . initializer ) ) {
807
+ text = getGoStringLiteral ( prop . initializer . text ) ;
808
+ }
809
+ else {
810
+ console . error ( `Expected string literal or array literal for quickInfos property, got ${ prop . initializer . getText ( ) } ` ) ;
811
+ return undefined ;
812
+ }
813
+ cmds . push ( {
814
+ kind : "quickInfoAt" ,
815
+ marker,
816
+ text,
817
+ docs,
818
+ } ) ;
819
+ }
820
+ return cmds ;
821
+ }
822
+ case "quickInfoExists" :
823
+ return [ {
824
+ kind : "quickInfoExists" ,
825
+ } ] ;
826
+ case "notQuickInfoExists" :
827
+ return [ {
828
+ kind : "notQuickInfoExists" ,
829
+ } ] ;
830
+ case "quickInfoIs" : {
831
+ if ( args . length < 1 || args . length > 2 ) {
832
+ console . error ( `Expected 1 or 2 arguments in quickInfoIs, got ${ args . map ( arg => arg . getText ( ) ) . join ( ", " ) } ` ) ;
833
+ return undefined ;
834
+ }
835
+ if ( ! ts . isStringLiteralLike ( args [ 0 ] ) ) {
836
+ console . error ( `Expected string literal for first argument in quickInfoIs, got ${ args [ 0 ] . getText ( ) } ` ) ;
837
+ return undefined ;
838
+ }
839
+ const text = getGoStringLiteral ( args [ 0 ] . text ) ;
840
+ let docs : string | undefined ;
841
+ if ( args [ 1 ] ) {
842
+ if ( ! ts . isStringLiteralLike ( args [ 1 ] ) ) {
843
+ console . error ( `Expected string literal for second argument in quickInfoIs, got ${ args [ 1 ] . getText ( ) } ` ) ;
844
+ return undefined ;
845
+ }
846
+ docs = getGoStringLiteral ( args [ 1 ] . text ) ;
847
+ }
848
+ return [ {
849
+ kind : "quickInfoIs" ,
850
+ text,
851
+ docs,
852
+ } ] ;
853
+ }
854
+ }
855
+ console . error ( `Unrecognized quick info function: ${ funcName } ` ) ;
856
+ return undefined ;
857
+ }
858
+
724
859
function parseKind ( expr : ts . Expression ) : string | undefined {
725
860
if ( ! ts . isStringLiteral ( expr ) ) {
726
861
console . error ( `Expected string literal for kind, got ${ expr . getText ( ) } ` ) ;
@@ -884,13 +1019,21 @@ interface EditCmd {
884
1019
goStatement : string ;
885
1020
}
886
1021
1022
+ interface VerifyQuickInfoCmd {
1023
+ kind : "quickInfoIs" | "quickInfoAt" | "quickInfoExists" | "notQuickInfoExists" ;
1024
+ marker ?: string ;
1025
+ text ?: string ;
1026
+ docs ?: string ;
1027
+ }
1028
+
887
1029
type Cmd =
888
1030
| VerifyCompletionsCmd
889
1031
| VerifyBaselineFindAllReferencesCmd
890
1032
| VerifyBaselineGoToDefinitionCmd
891
1033
| VerifyBaselineQuickInfoCmd
892
1034
| GoToCmd
893
- | EditCmd ;
1035
+ | EditCmd
1036
+ | VerifyQuickInfoCmd ;
894
1037
895
1038
function generateVerifyCompletions ( { marker, args, isNewIdentifierLocation } : VerifyCompletionsCmd ) : string {
896
1039
let expectedList : string ;
@@ -938,21 +1081,39 @@ function generateGoToCommand({ funcName, args }: GoToCmd): string {
938
1081
return `f.GoTo${ funcNameCapitalized } (t, ${ args . join ( ", " ) } )` ;
939
1082
}
940
1083
1084
+ function generateQuickInfoCommand ( { kind, marker, text, docs } : VerifyQuickInfoCmd ) : string {
1085
+ switch ( kind ) {
1086
+ case "quickInfoIs" :
1087
+ return `f.VerifyQuickInfoIs(t, ${ text ! } , ${ docs ? docs : `""` } )` ;
1088
+ case "quickInfoAt" :
1089
+ return `f.VerifyQuickInfoAt(t, ${ marker ! } , ${ text ? text : `""` } , ${ docs ? docs : `""` } )` ;
1090
+ case "quickInfoExists" :
1091
+ return `f.VerifyQuickInfoExists(t)` ;
1092
+ case "notQuickInfoExists" :
1093
+ return `f.VerifyNotQuickInfoExists(t)` ;
1094
+ }
1095
+ }
1096
+
941
1097
function generateCmd ( cmd : Cmd ) : string {
942
1098
switch ( cmd . kind ) {
943
1099
case "verifyCompletions" :
944
- return generateVerifyCompletions ( cmd as VerifyCompletionsCmd ) ;
1100
+ return generateVerifyCompletions ( cmd ) ;
945
1101
case "verifyBaselineFindAllReferences" :
946
- return generateBaselineFindAllReferences ( cmd as VerifyBaselineFindAllReferencesCmd ) ;
1102
+ return generateBaselineFindAllReferences ( cmd ) ;
947
1103
case "verifyBaselineGoToDefinition" :
948
- return generateBaselineGoToDefinition ( cmd as VerifyBaselineGoToDefinitionCmd ) ;
1104
+ return generateBaselineGoToDefinition ( cmd ) ;
949
1105
case "verifyBaselineQuickInfo" :
950
1106
// Quick Info -> Hover
951
1107
return `f.VerifyBaselineHover(t)` ;
952
1108
case "goTo" :
953
- return generateGoToCommand ( cmd as GoToCmd ) ;
1109
+ return generateGoToCommand ( cmd ) ;
954
1110
case "edit" :
955
1111
return cmd . goStatement ;
1112
+ case "quickInfoAt" :
1113
+ case "quickInfoIs" :
1114
+ case "quickInfoExists" :
1115
+ case "notQuickInfoExists" :
1116
+ return generateQuickInfoCommand ( cmd ) ;
956
1117
default :
957
1118
let neverCommand : never = cmd ;
958
1119
throw new Error ( `Unknown command kind: ${ neverCommand as Cmd [ "kind" ] } ` ) ;
0 commit comments