static NestedText GenFunc(Signature func, string funcName) { var argsWithoutFlags = func.Args .Filter(x => x.Kind.Match(_: () => true, flags: _ => false)) .ToArr(); var funcArgs = argsWithoutFlags .Map(x => ( name: x.Name, lowerName: Helpers.LowerFirst(x.Name), type: TgTypeConverter.ConvertArgType(x), isRef: TgTypeConverter.IsRefArgType(x) )).ToArray(); // usually it is a higher-order function, i am too lazy to modify the scheme just for this case var isWrapper = func.Args.Exists(x => x.Type == TgType.OfTypeRef("X") || x.Type == TgType.OfTypeRef("!X")); var resType = isWrapper ? "TFuncRes" : TgTypeConverter.ConvertType(func.ResultType); var classAccess = isWrapper ? "" : "public "; var classTemplates = isWrapper ? "<TFunc, TFuncRes>" : ""; var classAnnotations = isWrapper ? $": ITgFunc<{resType}> where TFunc : class, ITgFunc<{resType}>" : $": ITgFunc<{resType}>, IEquatable<{funcName}>, IComparable<{funcName}>, IComparable"; var resDes = isWrapper ? "Query.DeserializeResult(br);" // it is 'Query' all the time, i am too lazy : Concat("Read(br, ", SerializerGen.GenTypeDeserializer(func.ResultType), ");"); var resultDeserializer = Scope( Line($"{resType} ITgFunc<{resType}>.DeserializeResult(BinaryReader br) =>"), Indent(1, Line(resDes)) ); return(Scope( Line($"{classAccess}sealed class {funcName}{classTemplates} {classAnnotations}"), Line("{"), IndentedScope(1, funcArgs.Map(arg => Line($"public {arg.type} {arg.name} {{ get; }}")).Scope(), Scope( Line(""), Scope( Line($"public {funcName}("), IndentedScope(1, $",{Environment.NewLine}", funcArgs.Map(arg => Line($"{arg.type} {arg.lowerName}")) ), Line(") {"), IndentedScope(1, funcArgs.Map(arg => Line( $"{arg.name} = {arg.lowerName}" + $"{(arg.isRef ? $" ?? throw new ArgumentNullException(nameof({arg.lowerName}))" : "")};" )) ), Line("}") ), Line(""), Line(""), isWrapper ? Scope(new NestedText[0]) : Scope( WithGen.GenWith(argsWithoutFlags, funcName), Line(""), RelationsGen.GenRelations(funcName, argsWithoutFlags), Line("") ), SerializerGen.GenSerializer(func.Args, typeNumber: func.TypeNumber, "ITgSerializable.Serialize"), Line(""), resultDeserializer ) ), Line("}") )); }
public static string ConvertType(TgType type, bool cmpWrapper) => type.Match(