@@ -801,7 +801,29 @@ static tokenInfo * parseReceiver (tokenInfo *const token, int *corkIndex)
801801 return receiver_type_token ;
802802}
803803
804- static intArray * parseTypeParameters (tokenInfo * const token , collector * collector )
804+ static void attachConstrain (intArray * tparams_indexes , collector * constrain )
805+ {
806+ collectorTruncate (constrain , false);
807+ if (collectorIsEmpty (constrain ))
808+ return ;
809+
810+ const char * constrain_cstr = vStringValue (constrain -> str );
811+ for (unsigned int i = intArrayCount (tparams_indexes ); i > 0 ; i -- )
812+ {
813+ int index = intArrayItem (tparams_indexes , i - 1 );
814+ tagEntryInfo * e = getEntryInCorkQueue (index );
815+ if (!e )
816+ continue ; /* Maybe "_" */
817+
818+ if (e -> extensionFields .typeRef [0 ])
819+ return ;
820+
821+ e -> extensionFields .typeRef [0 ] = eStrdup ("constrain" );
822+ e -> extensionFields .typeRef [1 ] = eStrdup (constrain_cstr );
823+ }
824+ }
825+
826+ static intArray * parseTypeParameters (tokenInfo * const token , collector * tparams )
805827{
806828 // TypeParameters = "[" TypeParamList [ "," ] "]" .
807829 // TypeParamList = TypeParamDecl { "," TypeParamDecl } .
@@ -811,40 +833,63 @@ static intArray * parseTypeParameters (tokenInfo *const token, collector *collec
811833
812834 int nest_level = 1 ;
813835 bool expecting_param = true;
814- intArray * tparams = intArrayNew ();
836+ intArray * tparams_indexes = intArrayNew ();
837+ bool expecting_constrain = false;
838+
839+ vString * buffer = vStringNew ();
840+ collector constrain = COLLECTOR (buffer );
815841
816842 while (nest_level > 0 && !isType (token , TOKEN_EOF ))
817843 {
818- readTokenFull (token , collector );
844+ readTokenFull (token , tparams );
819845 if (isType (token , TOKEN_OPEN_PAREN )
820846 || isType (token , TOKEN_OPEN_CURLY )
821847 || isType (token , TOKEN_OPEN_SQUARE ))
848+ {
822849 nest_level ++ ;
850+ collectorAppendToken (& constrain , token );
851+ }
823852 else if (isType (token , TOKEN_CLOSE_PAREN )
824853 || isType (token , TOKEN_CLOSE_CURLY )
825854 || isType (token , TOKEN_CLOSE_SQUARE ))
855+ {
826856 nest_level -- ;
857+ if (nest_level == 0 )
858+ {
859+ attachConstrain (tparams_indexes , & constrain );
860+ collectorReset (& constrain );
861+ continue ;
862+ }
863+ collectorAppendToken (& constrain , token );
864+ }
827865 else if (nest_level == 1
828866 && isType (token , TOKEN_IDENTIFIER )
829867 && expecting_param )
830868 {
869+ attachConstrain (tparams_indexes , & constrain );
870+ collectorReset (& constrain );
871+
831872 expecting_param = false;
873+ expecting_constrain = true;
832874 int index = makeTag (token , GOTAG_TPARAM , CORK_NIL , NULL , NULL );
833- intArrayAdd (tparams , index );
875+ intArrayAdd (tparams_indexes , index );
834876 }
835877 else if (nest_level == 1
836878 && isType (token , TOKEN_COMMA ))
837879 {
838- /* TODO: put the tokens to typeref:constrain:... of the
839- * tparam tag */
840880 expecting_param = true;
881+ expecting_constrain = false;
841882 }
883+ else if (expecting_constrain )
884+ collectorAppendToken (& constrain , token );
842885 }
843886
887+ vStringDelete (buffer );
888+
844889 /* Read the next token as the other parser* functions do.
845890 * However, don't put the token to the collector. */
846891 readToken (token );
847- return tparams ;
892+ return tparams_indexes ;
848893}
849894
850895static void parseFunctionOrMethod (tokenInfo * const token , const int scope )
0 commit comments