@@ -130,6 +130,27 @@ static void Main(string[] args)
130130 functionsJson = JObject . Load ( jr ) ;
131131 }
132132
133+ JObject variantsJson = null ;
134+ if ( File . Exists ( Path . Combine ( AppContext . BaseDirectory , "variants.json" ) ) )
135+ {
136+ using ( StreamReader fs = File . OpenText ( Path . Combine ( AppContext . BaseDirectory , "variants.json" ) ) )
137+ using ( JsonTextReader jr = new JsonTextReader ( fs ) )
138+ {
139+ variantsJson = JObject . Load ( jr ) ;
140+ }
141+ }
142+
143+ Dictionary < string , MethodVariant > variants = new Dictionary < string , MethodVariant > ( ) ;
144+ foreach ( var jt in variantsJson . Children ( ) )
145+ {
146+ JProperty jp = ( JProperty ) jt ;
147+ ParameterVariant [ ] methodVariants = jp . Values ( ) . Select ( jv =>
148+ {
149+ return new ParameterVariant ( jv [ "name" ] . ToString ( ) , jv [ "type" ] . ToString ( ) , jv [ "variants" ] . Select ( s => s . ToString ( ) ) . ToArray ( ) ) ;
150+ } ) . ToArray ( ) ;
151+ variants . Add ( jp . Name , new MethodVariant ( jp . Name , methodVariants ) ) ;
152+ }
153+
133154 EnumDefinition [ ] enums = typesJson [ "enums" ] . Select ( jt =>
134155 {
135156 JProperty jp = ( JProperty ) jt ;
@@ -195,11 +216,20 @@ static void Main(string[] args)
195216
196217 List < TypeReference > parameters = new List < TypeReference > ( ) ;
197218
219+ // find any variants that can be applied to the parameters of this method based on the method name
220+ MethodVariant methodVariants = null ;
221+ variants . TryGetValue ( jp . Name , out methodVariants ) ;
222+
198223 foreach ( JToken p in val [ "argsT" ] )
199224 {
200225 string pType = p [ "type" ] . ToString ( ) ;
201226 string pName = p [ "name" ] . ToString ( ) ;
202- parameters . Add ( new TypeReference ( pName , pType , enums ) ) ;
227+
228+ // if there are possible variants for this method then try to match them based on the parameter name and expected type
229+ ParameterVariant matchingVariant = methodVariants ? . Parameters . Where ( pv => pv . Name == pName && pv . OriginalType == pType ) . FirstOrDefault ( ) ?? null ;
230+ if ( matchingVariant != null ) matchingVariant . Used = true ;
231+
232+ parameters . Add ( new TypeReference ( pName , pType , enums , matchingVariant ? . VariantTypes ) ) ;
203233 }
204234
205235 Dictionary < string , string > defaultValues = new Dictionary < string , string > ( ) ;
@@ -231,7 +261,7 @@ static void Main(string[] args)
231261 isDestructor ) ;
232262 } ) . Where ( od => od != null ) . ToArray ( ) ;
233263
234- return new FunctionDefinition ( name , overloads ) ;
264+ return new FunctionDefinition ( name , overloads , enums ) ;
235265 } ) . OrderBy ( fd => fd . Name ) . ToArray ( ) ;
236266
237267 foreach ( EnumDefinition ed in enums )
@@ -545,6 +575,14 @@ static void Main(string[] args)
545575 writer . PopBlock ( ) ;
546576 writer . PopBlock ( ) ;
547577 }
578+
579+ foreach ( var method in variants )
580+ {
581+ foreach ( var variant in method . Value . Parameters )
582+ {
583+ if ( ! variant . Used ) Console . WriteLine ( $ "Error: Variants targetting parameter { variant . Name } with type { variant . OriginalType } could not be applied to method { method . Key } .") ;
584+ }
585+ }
548586 }
549587
550588 private static bool IsStringFieldName ( string name )
@@ -963,6 +1001,38 @@ private static string CorrectIdentifier(string identifier)
9631001 }
9641002 }
9651003
1004+ class MethodVariant
1005+ {
1006+ public string Name { get ; }
1007+
1008+ public ParameterVariant [ ] Parameters { get ; }
1009+
1010+ public MethodVariant ( string name , ParameterVariant [ ] parameters )
1011+ {
1012+ Name = name ;
1013+ Parameters = parameters ;
1014+ }
1015+ }
1016+
1017+ class ParameterVariant
1018+ {
1019+ public string Name { get ; }
1020+
1021+ public string OriginalType { get ; }
1022+
1023+ public string [ ] VariantTypes { get ; }
1024+
1025+ public bool Used { get ; set ; }
1026+
1027+ public ParameterVariant ( string name , string originalType , string [ ] variantTypes )
1028+ {
1029+ Name = name ;
1030+ OriginalType = originalType ;
1031+ VariantTypes = variantTypes ;
1032+ Used = false ;
1033+ }
1034+ }
1035+
9661036 class EnumDefinition
9671037 {
9681038 private readonly Dictionary < string , string > _sanitizedNames ;
@@ -1049,11 +1119,18 @@ class TypeReference
10491119 public string TemplateType { get ; }
10501120 public int ArraySize { get ; }
10511121 public bool IsFunctionPointer { get ; }
1122+ public string [ ] TypeVariants { get ; }
10521123
10531124 public TypeReference ( string name , string type , EnumDefinition [ ] enums )
1054- : this ( name , type , null , enums ) { }
1125+ : this ( name , type , null , enums , null ) { }
1126+
1127+ public TypeReference ( string name , string type , EnumDefinition [ ] enums , string [ ] typeVariants )
1128+ : this ( name , type , null , enums , typeVariants ) { }
10551129
10561130 public TypeReference ( string name , string type , string templateType , EnumDefinition [ ] enums )
1131+ : this ( name , type , templateType , enums , null ) { }
1132+
1133+ public TypeReference ( string name , string type , string templateType , EnumDefinition [ ] enums , string [ ] typeVariants )
10571134 {
10581135 Name = name ;
10591136 Type = type . Replace ( "const" , string . Empty ) . Trim ( ) ;
@@ -1082,6 +1159,8 @@ public TypeReference(string name, string type, string templateType, EnumDefiniti
10821159 }
10831160
10841161 IsFunctionPointer = Type . IndexOf ( '(' ) != - 1 ;
1162+
1163+ TypeVariants = typeVariants ;
10851164 }
10861165
10871166 private int ParseSizeString ( string sizePart , EnumDefinition [ ] enums )
@@ -1117,17 +1196,76 @@ private int ParseSizeString(string sizePart, EnumDefinition[] enums)
11171196
11181197 return ret ;
11191198 }
1199+
1200+ public TypeReference WithVariant ( int variantIndex , EnumDefinition [ ] enums )
1201+ {
1202+ if ( variantIndex == 0 ) return this ;
1203+ else return new TypeReference ( Name , TypeVariants [ variantIndex - 1 ] , TemplateType , enums ) ;
1204+ }
11201205 }
11211206
11221207 class FunctionDefinition
11231208 {
11241209 public string Name { get ; }
11251210 public OverloadDefinition [ ] Overloads { get ; }
11261211
1127- public FunctionDefinition ( string name , OverloadDefinition [ ] overloads )
1212+ public FunctionDefinition ( string name , OverloadDefinition [ ] overloads , EnumDefinition [ ] enums )
11281213 {
11291214 Name = name ;
1130- Overloads = overloads ;
1215+ Overloads = ExpandOverloadVariants ( overloads , enums ) ;
1216+ }
1217+
1218+ private OverloadDefinition [ ] ExpandOverloadVariants ( OverloadDefinition [ ] overloads , EnumDefinition [ ] enums )
1219+ {
1220+ List < OverloadDefinition > newDefinitions = new List < OverloadDefinition > ( ) ;
1221+
1222+ foreach ( OverloadDefinition overload in overloads )
1223+ {
1224+ bool hasVariants = false ;
1225+ int [ ] variantCounts = new int [ overload . Parameters . Length ] ;
1226+
1227+ for ( int i = 0 ; i < overload . Parameters . Length ; i ++ )
1228+ {
1229+ if ( overload . Parameters [ i ] . TypeVariants != null )
1230+ {
1231+ hasVariants = true ;
1232+ variantCounts [ i ] = overload . Parameters [ i ] . TypeVariants . Length + 1 ;
1233+ }
1234+ else
1235+ {
1236+ variantCounts [ i ] = 1 ;
1237+ }
1238+ }
1239+
1240+ if ( hasVariants )
1241+ {
1242+ int totalVariants = variantCounts [ 0 ] ;
1243+ for ( int i = 1 ; i < variantCounts . Length ; i ++ ) totalVariants *= variantCounts [ i ] ;
1244+
1245+ for ( int i = 0 ; i < totalVariants ; i ++ )
1246+ {
1247+ TypeReference [ ] parameters = new TypeReference [ overload . Parameters . Length ] ;
1248+ int div = 1 ;
1249+
1250+ for ( int j = 0 ; j < parameters . Length ; j ++ )
1251+ {
1252+ int k = ( i / div ) % variantCounts [ j ] ;
1253+
1254+ parameters [ j ] = overload . Parameters [ j ] . WithVariant ( k , enums ) ;
1255+
1256+ if ( j > 0 ) div *= variantCounts [ j ] ;
1257+ }
1258+
1259+ newDefinitions . Add ( overload . WithParameters ( parameters ) ) ;
1260+ }
1261+ }
1262+ else
1263+ {
1264+ newDefinitions . Add ( overload ) ;
1265+ }
1266+ }
1267+
1268+ return newDefinitions . ToArray ( ) ;
11311269 }
11321270 }
11331271
@@ -1166,6 +1304,11 @@ public OverloadDefinition(
11661304 IsConstructor = isConstructor ;
11671305 IsDestructor = isDestructor ;
11681306 }
1307+
1308+ public OverloadDefinition WithParameters ( TypeReference [ ] parameters )
1309+ {
1310+ return new OverloadDefinition ( ExportedName , FriendlyName , parameters , DefaultValues , ReturnType , StructName , Comment , IsConstructor , IsDestructor ) ;
1311+ }
11691312 }
11701313
11711314 class MarshalledParameter
0 commit comments