@@ -144,16 +144,30 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined {
144144 }
145145 const namespace = callExpression . expression . expression ;
146146 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 ) ) {
148148 console . error ( `Expected identifiers for namespace and function, got ${ namespace . getText ( ) } and ${ func . getText ( ) } ` ) ;
149149 return undefined ;
150150 }
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+ }
151159 // `verify.(...)`
152160 if ( namespace . text === "verify" ) {
153161 switch ( func . text ) {
154162 case "completions" :
155163 // `verify.completions(...)`
156164 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 ) ;
157171 case "baselineFindAllReferences" :
158172 // `verify.baselineFindAllReferences(...)`
159173 return [ parseBaselineFindAllReferencesArgs ( callExpression . arguments ) ] ;
@@ -721,6 +735,127 @@ function parseBaselineQuickInfo(args: ts.NodeArray<ts.Expression>): Cmd {
721735 } ;
722736}
723737
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+
724859function parseKind ( expr : ts . Expression ) : string | undefined {
725860 if ( ! ts . isStringLiteral ( expr ) ) {
726861 console . error ( `Expected string literal for kind, got ${ expr . getText ( ) } ` ) ;
@@ -884,13 +1019,21 @@ interface EditCmd {
8841019 goStatement : string ;
8851020}
8861021
1022+ interface VerifyQuickInfoCmd {
1023+ kind : "quickInfoIs" | "quickInfoAt" | "quickInfoExists" | "notQuickInfoExists" ;
1024+ marker ?: string ;
1025+ text ?: string ;
1026+ docs ?: string ;
1027+ }
1028+
8871029type Cmd =
8881030 | VerifyCompletionsCmd
8891031 | VerifyBaselineFindAllReferencesCmd
8901032 | VerifyBaselineGoToDefinitionCmd
8911033 | VerifyBaselineQuickInfoCmd
8921034 | GoToCmd
893- | EditCmd ;
1035+ | EditCmd
1036+ | VerifyQuickInfoCmd ;
8941037
8951038function generateVerifyCompletions ( { marker, args, isNewIdentifierLocation } : VerifyCompletionsCmd ) : string {
8961039 let expectedList : string ;
@@ -938,21 +1081,39 @@ function generateGoToCommand({ funcName, args }: GoToCmd): string {
9381081 return `f.GoTo${ funcNameCapitalized } (t, ${ args . join ( ", " ) } )` ;
9391082}
9401083
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+
9411097function generateCmd ( cmd : Cmd ) : string {
9421098 switch ( cmd . kind ) {
9431099 case "verifyCompletions" :
944- return generateVerifyCompletions ( cmd as VerifyCompletionsCmd ) ;
1100+ return generateVerifyCompletions ( cmd ) ;
9451101 case "verifyBaselineFindAllReferences" :
946- return generateBaselineFindAllReferences ( cmd as VerifyBaselineFindAllReferencesCmd ) ;
1102+ return generateBaselineFindAllReferences ( cmd ) ;
9471103 case "verifyBaselineGoToDefinition" :
948- return generateBaselineGoToDefinition ( cmd as VerifyBaselineGoToDefinitionCmd ) ;
1104+ return generateBaselineGoToDefinition ( cmd ) ;
9491105 case "verifyBaselineQuickInfo" :
9501106 // Quick Info -> Hover
9511107 return `f.VerifyBaselineHover(t)` ;
9521108 case "goTo" :
953- return generateGoToCommand ( cmd as GoToCmd ) ;
1109+ return generateGoToCommand ( cmd ) ;
9541110 case "edit" :
9551111 return cmd . goStatement ;
1112+ case "quickInfoAt" :
1113+ case "quickInfoIs" :
1114+ case "quickInfoExists" :
1115+ case "notQuickInfoExists" :
1116+ return generateQuickInfoCommand ( cmd ) ;
9561117 default :
9571118 let neverCommand : never = cmd ;
9581119 throw new Error ( `Unknown command kind: ${ neverCommand as Cmd [ "kind" ] } ` ) ;
0 commit comments