public static void GenerateMember(this CSharpSources gen, Class @class, Action <Class> generate, bool isVoid = false) { if (@class != null && @class.IsDependent) { foreach (var parameter in @class.TemplateParameters) { gen.WriteLine($"var __{parameter.Name} = typeof({parameter.Name});"); } foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated)) { WriteTemplateSpecializationCheck(gen, @class, specialization); gen.WriteOpenBraceAndIndent(); generate(specialization); if (isVoid) { gen.WriteLine("return;"); } gen.UnindentAndWriteCloseBrace(); } ThrowException(gen, @class); } else { generate(@class); } }
private static void WriteTemplateSpecializationCheck(CSharpSources gen, Class @class, ClassTemplateSpecialization specialization) { gen.WriteLine("if ({0})", string.Join(" && ", Enumerable.Range(0, @class.TemplateParameters.Count).Select( i => string.Format("__{0}.IsAssignableFrom(typeof({1}))", @class.TemplateParameters[i].Name, specialization.Arguments[i].Type.Type.Desugar())))); }
public static void GenerateField(this CSharpSources gen, Class @class, Field field, Action <Field, Class, QualifiedType> generate, bool isVoid) { if (@class.IsDependent) { if (@class.Fields.Any(f => f.Type.IsDependent)) { foreach (var parameter in @class.TemplateParameters) { gen.WriteLine($"var __{parameter.Name} = typeof({parameter.Name});"); } foreach (var specialization in @class.Specializations.Where(s => s.IsGenerated)) { WriteTemplateSpecializationCheck(gen, @class, specialization); gen.WriteOpenBraceAndIndent(); var specializedField = specialization.Fields.First( f => f.OriginalName == field.OriginalName); generate(specializedField, specialization, field.QualifiedType); if (isVoid) { gen.WriteLine("return;"); } gen.UnindentAndWriteCloseBrace(); } ThrowException(gen, @class); } else { var specialization = @class.Specializations[0]; var specializedField = specialization.Fields.First( f => f.OriginalName == field.OriginalName); generate(specializedField, specialization, field.QualifiedType); } } else { generate(field, @class.IsDependent ? @class.Specializations[0] : @class, field.QualifiedType); } }
private static void WriteTemplateSpecializationCheck(CSharpSources gen, Class @class, ClassTemplateSpecialization specialization) { gen.WriteLine("if ({0})", string.Join(" && ", Enumerable.Range(0, @class.TemplateParameters.Count).Select( i => { CppSharp.AST.Type type = specialization.Arguments[i].Type.Type; return(type.IsPointerToPrimitiveType() && !type.IsConstCharString() ? $"__{@class.TemplateParameters[i].Name}.FullName == \"System.IntPtr\"" : $"__{@class.TemplateParameters[i].Name}.IsAssignableFrom(typeof({type}))"); }))); }
private static void ThrowException(CSharpSources gen, Class @class) { var typePrinter = new CSharpTypePrinter(gen.Context); var supportedTypes = string.Join(", ", @class.Specializations.Where(s => !s.Ignore).Select(s => $@"<{string.Join(", ", s.Arguments.Select(a => typePrinter.VisitTemplateArgument(a)))}>")); var typeArguments = string.Join(", ", @class.TemplateParameters.Select(p => p.Name)); var managedTypes = string.Join(", ", @class.TemplateParameters.Select(p => $"typeof({p.Name}).FullName")); gen.WriteLine($"throw new ArgumentOutOfRangeException(\"{typeArguments}\", " + $@"string.Join("", "", new[] {{ {managedTypes} }}), " + $"\"{@class.Visit(typePrinter)} maps a C++ template class and therefore it only supports a limited set of types and their subclasses: {supportedTypes}.\");"); }