public override async Task GenerateInClass(ObjectGeneration obj, FileGeneration fg) { if (obj.GetObjectData().ObjectType != ObjectType.Mod) { return; } var objData = obj.GetObjectData(); // Game release member if (objData.GameReleaseOptions != null) { fg.AppendLine($"public {ReleaseEnumName(obj)} {ReleaseEnumName(obj)} {{ get; }}"); fg.AppendLine($"public override {nameof(GameRelease)} GameRelease => {ReleaseEnumName(obj)}.ToGameRelease();"); } else { fg.AppendLine($"public override {nameof(GameRelease)} GameRelease => {nameof(GameRelease)}.{obj.GetObjectData().GameCategory};"); } // Interfaces fg.AppendLine($"IGroupGetter<T> {nameof(IModGetter)}.{nameof(IModGetter.GetTopLevelGroup)}<T>() => this.{nameof(IModGetter.GetTopLevelGroup)}<T>();"); fg.AppendLine($"IGroupGetter {nameof(IModGetter)}.{nameof(IModGetter.GetTopLevelGroup)}(Type type) => this.{nameof(IModGetter.GetTopLevelGroup)}(type);"); fg.AppendLine($"IGroup<T> {nameof(IMod)}.{nameof(IMod.GetTopLevelGroup)}<T>() => this.{nameof(IMod.GetTopLevelGroup)}<T>();"); fg.AppendLine($"IGroup {nameof(IMod)}.{nameof(IMod.GetTopLevelGroup)}(Type type) => this.{nameof(IMod.GetTopLevelGroup)}(type);"); fg.AppendLine($"void IModGetter.WriteToBinary({nameof(FilePath)} path, {nameof(BinaryWriteParameters)}? param, IFileSystem? fileSystem) => this.WriteToBinary(path, importMask: null, param: param, fileSystem: fileSystem);"); fg.AppendLine($"void IModGetter.WriteToBinaryParallel({nameof(FilePath)} path, {nameof(BinaryWriteParameters)}? param, IFileSystem? fileSystem, {nameof(ParallelWriteParameters)}? parallelWriteParams) => this.WriteToBinaryParallel(path, param, fileSystem: fileSystem, parallelParam: parallelWriteParams);"); fg.AppendLine($"IMask<bool> {nameof(IEqualsMask)}.{nameof(IEqualsMask.GetEqualsMask)}(object rhs, EqualsMaskHelper.Include include = EqualsMaskHelper.Include.OnlyFailures) => {obj.MixInClassName}.GetEqualsMask(this, ({obj.Interface(getter: true, internalInterface: true)})rhs, include);"); // Localization enabled member if (obj.GetObjectData().UsesStringFiles) { fg.AppendLine($"public override bool CanUseLocalization => true;"); fg.AppendLine($"public override bool UsingLocalization"); using (new BraceWrapper(fg)) { fg.AppendLine($"get => this.ModHeader.Flags.HasFlag({obj.GetObjectData().GameCategory}ModHeader.HeaderFlag.Localized);"); fg.AppendLine($"set => this.ModHeader.Flags = this.ModHeader.Flags.SetFlag({obj.GetObjectData().GameCategory}ModHeader.HeaderFlag.Localized, value);"); } } else { fg.AppendLine($"public override bool CanUseLocalization => false;"); fg.AppendLine($"public override bool UsingLocalization"); using (new BraceWrapper(fg)) { fg.AppendLine("get => false;"); fg.AppendLine("set => throw new ArgumentException(\"Tried to set localization flag on unsupported mod type\");"); } } // Master references member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IList<MasterReference> IMod.MasterReferences => this.ModHeader.MasterReferences;"); fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"IReadOnlyList<IMasterReferenceGetter> IModGetter.MasterReferences => this.ModHeader.MasterReferences;"); // NextObjectID member fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"uint IMod.NextFormID"); using (new BraceWrapper(fg)) { fg.AppendLine($"get => this.ModHeader.Stats.NextFormID;"); fg.AppendLine($"set => this.ModHeader.Stats.NextFormID = value;"); } fg.AppendLine($"[DebuggerBrowsable(DebuggerBrowsableState.Never)]"); fg.AppendLine($"uint IModGetter.NextFormID => this.ModHeader.Stats.NextFormID;"); using (var args = new FunctionWrapper(fg, $"public {obj.Name}")) { args.Add($"{nameof(ModKey)} modKey"); if (objData.GameReleaseOptions != null) { args.Add($"{ReleaseEnumName(obj)} release"); } } using (new DepthWrapper(fg)) { fg.AppendLine(": base(modKey)"); } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NextFormID = GetDefaultInitialNextFormID();"); if (objData.GameReleaseOptions != null) { fg.AppendLine($"this.{ReleaseEnumName(obj)} = release;"); } await obj.GenerateInitializer(fg); fg.AppendLine($"CustomCtor();"); } using (var args = new FunctionWrapper(fg, "public void AddRecords")) { args.Add($"{obj.Name} rhsMod"); args.Add($"GroupMask? mask = null"); } using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"if (mask?.{field.Name} ?? true)"); using (new BraceWrapper(fg)) { if (loqui.TargetObjectGeneration.Name == $"{obj.ProtoGen.Protocol.Namespace}Group") { fg.AppendLine($"this.{field.Name}.RecordCache.Set(rhsMod.{field.Name}.RecordCache.Items);"); } else { fg.AppendLine($"if (rhsMod.{field.Name}.Records.Count > 0)"); using (new BraceWrapper(fg)) { fg.AppendLine("throw new NotImplementedException(\"Cell additions need implementing\");"); } } } } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public override void SyncRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("this.ModHeader.Stats.NumRecords = GetRecordCount();"); } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public uint GetRecordCount")) { } using (new BraceWrapper(fg)) { fg.AppendLine("uint count = (uint)this.EnumerateMajorRecords().Count();"); foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } if (loqui.TargetObjectGeneration.Name.EndsWith("ListGroup")) { fg.AppendLine($"count += {field.Name}.Records.Count > 0 ? 1 : default(uint);"); } else { fg.AppendLine($"count += {field.Name}.RecordCache.Count > 0 ? 1 : default(uint);"); } } fg.AppendLine("GetCustomRecordCount((customCount) => count += customCount);"); fg.AppendLine("return count;"); } fg.AppendLine(); fg.AppendLine("partial void GetCustomRecordCount(Action<uint> setter);"); fg.AppendLine(); await base.GenerateInClass(obj, fg); }
private void GenerateWriteParallel(ObjectGeneration obj, FileGeneration fg) { LoquiType groupInstance = null; LoquiType listGroupInstance = null; var objData = obj.GetObjectData(); using (var args = new FunctionWrapper(fg, "public static void WriteParallel")) { args.Add($"{obj.Interface(getter: true, internalInterface: false)} item"); args.Add($"Stream stream"); args.Add($"{nameof(BinaryWriteParameters)} param"); args.Add($"{nameof(ParallelWriteParameters)} parallelParam"); args.Add($"ModKey modKey"); } using (new BraceWrapper(fg)) { string gameConstantsStr; if (objData.GameReleaseOptions == null) { gameConstantsStr = $"{nameof(GameConstants)}.{obj.GetObjectData().GameCategory}"; } else { fg.AppendLine($"var gameConstants = {nameof(GameConstants)}.Get(item.{ReleaseEnumName(obj)}.ToGameRelease());"); gameConstantsStr = $"gameConstants"; } fg.AppendLine($"var bundle = new {nameof(WritingBundle)}({gameConstantsStr})"); using (new BraceWrapper(fg) { AppendSemicolon = true }) { fg.AppendLine("StringsWriter = param.StringsWriter,"); fg.AppendLine("TargetLanguageOverride = param.TargetLanguageOverride,"); } fg.AppendLine($"var writer = new MutagenWriter(stream, bundle);"); using (var args = new ArgsWrapper(fg, $"{nameof(ModHeaderWriteLogic)}.{nameof(ModHeaderWriteLogic.WriteHeader)}")) { args.AddPassArg("param"); args.AddPassArg("writer"); args.Add("mod: item"); args.Add("modHeader: item.ModHeader.DeepCopy()"); args.AddPassArg("modKey"); } int groupCount = obj.IterateFields() .Select(f => f as LoquiType) .Where(l => l != null) .Where(l => l.TargetObjectGeneration?.GetObjectData().ObjectType == ObjectType.Group) .Count(); fg.AppendLine($"Stream[] outputStreams = new Stream[{groupCount}];"); fg.AppendLine($"List<Action> toDo = new List<Action>();"); int i = 0; foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration?.GetObjectData().ObjectType != ObjectType.Group) { continue; } if (loqui.TargetObjectGeneration.Name.EndsWith("ListGroup")) { listGroupInstance = loqui; } else { groupInstance = loqui; } if (loqui.GetGroupTarget().GetObjectData().CustomBinaryEnd == CustomEnd.Off && !loqui.TargetObjectGeneration.Name.EndsWith("ListGroup")) { fg.AppendLine($"toDo.Add(() => WriteGroupParallel(item.{field.Name}, {i}, outputStreams, bundle, parallelParam));"); } else { fg.AppendLine($"toDo.Add(() => Write{field.Name}Parallel(item.{field.Name}, {i}, outputStreams, bundle, parallelParam));"); } i++; } fg.AppendLine("Parallel.Invoke(parallelParam.ParallelOptions, toDo.ToArray());"); using (var args = new ArgsWrapper(fg, $"{nameof(PluginUtilityTranslation)}.{nameof(PluginUtilityTranslation.CompileStreamsInto)}")) { args.Add("outputStreams.NotNull()"); args.Add("stream"); } } fg.AppendLine(); if (groupInstance != null) { using (var args = new FunctionWrapper(fg, $"public static void WriteGroupParallel<T>")) { args.Add($"I{obj.ProtoGen.Protocol.Namespace}GroupGetter<T> group"); args.Add("int targetIndex"); args.Add("Stream[] streamDepositArray"); args.Add($"{nameof(WritingBundle)} bundle"); args.Add($"{nameof(ParallelWriteParameters)} parallelParam"); args.Wheres.AddRange(groupInstance.TargetObjectGeneration.GenerateWhereClauses(LoquiInterfaceType.IGetter, groupInstance.TargetObjectGeneration.Generics)); } using (new BraceWrapper(fg)) { fg.AppendLine("if (group.RecordCache.Count == 0) return;"); fg.AppendLine($"var cuts = group.Cut(parallelParam.CutCount).ToArray();"); fg.AppendLine($"Stream[] subStreams = new Stream[cuts.Length + 1];"); fg.AppendLine($"byte[] groupBytes = new byte[bundle.Constants.GroupConstants.HeaderLength];"); fg.AppendLine($"BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);"); fg.AppendLine($"var groupByteStream = new MemoryStream(groupBytes);"); fg.AppendLine($"using (var stream = new MutagenWriter(groupByteStream, bundle.Constants, dispose: false))"); using (new BraceWrapper(fg)) { fg.AppendLine($"stream.Position += 8;"); fg.AppendLine($"{obj.ProtoGen.Protocol.Namespace}GroupBinaryWriteTranslation.WriteEmbedded<T>(group, stream);"); } fg.AppendLine($"subStreams[0] = groupByteStream;"); fg.AppendLine($"Parallel.ForEach(cuts, parallelParam.ParallelOptions, (cutItems, state, counter) =>"); using (new BraceWrapper(fg) { AppendSemicolon = true, AppendParenthesis = true }) { fg.AppendLine($"{nameof(MemoryTributary)} trib = new {nameof(MemoryTributary)}();"); fg.AppendLine($"using (var stream = new MutagenWriter(trib, bundle with {{}}, dispose: false))"); using (new BraceWrapper(fg)) { fg.AppendLine($"foreach (var item in cutItems)"); using (new BraceWrapper(fg)) { fg.AppendLine($"item.WriteToBinary(stream);"); } } fg.AppendLine($"subStreams[(int)counter + 1] = trib;"); } fg.AppendLine($"{nameof(PluginUtilityTranslation)}.CompileSetGroupLength(subStreams, groupBytes);"); fg.AppendLine($"streamDepositArray[targetIndex] = new CompositeReadStream(subStreams, resetPositions: true);"); } fg.AppendLine(); } }
public override async Task GenerateInVoid(ObjectGeneration obj, FileGeneration fg) { if (obj.GetObjectType() != ObjectType.Mod) { return; } using (new NamespaceWrapper(fg, obj.Namespace, fileScoped: false)) { var objData = obj.GetObjectData(); fg.AppendLine("public class GroupMask"); using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration == null) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"public bool {loqui.Name};"); } fg.AppendLine("public GroupMask()"); using (new BraceWrapper(fg)) { } fg.AppendLine("public GroupMask(bool defaultValue)"); using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration == null) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"{loqui.Name} = defaultValue;"); } } } fg.AppendLine(); fg.AppendLine($"public interface I{obj.Name}DisposableGetter : {obj.Interface(getter: true, internalInterface: true)}, IModDisposeGetter"); using (new BraceWrapper(fg)) { } fg.AppendLine(); if (objData.GameReleaseOptions != null) { using (var comment = new CommentWrapper(fg)) { comment.Summary.AppendLine($"Different game release versions a {ModName(obj)} mod can have"); } fg.AppendLine($"public enum {ReleaseEnumName(obj)}"); using (new BraceWrapper(fg)) { using (var comma = new CommaWrapper(fg)) { foreach (var opt in objData.GameReleaseOptions) { comma.Add($"{opt} = {(int)opt}"); } } } fg.AppendLine(); using (var c = new ClassWrapper(fg, $"{ReleaseEnumName(obj)}Ext")) { c.Static = true; } using (new BraceWrapper(fg)) { using (var args = new FunctionWrapper(fg, $"public static {nameof(GameRelease)} ToGameRelease")) { args.Add($"this {ReleaseEnumName(obj)} release"); } using (new BraceWrapper(fg)) { fg.AppendLine("return release switch"); using (new BraceWrapper(fg) { AppendSemicolon = true }) { using (var comma = new CommaWrapper(fg)) { foreach (var item in objData.GameReleaseOptions) { comma.Add($"{ReleaseEnumName(obj)}.{item} => {nameof(GameRelease)}.{item}"); } comma.Add("_ => throw new ArgumentException()"); } } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static {ReleaseEnumName(obj)} To{ReleaseEnumName(obj)}")) { args.Add($"this {nameof(GameRelease)} release"); } using (new BraceWrapper(fg)) { fg.AppendLine("return release switch"); using (new BraceWrapper(fg) { AppendSemicolon = true }) { using (var comma = new CommaWrapper(fg)) { foreach (var item in objData.GameReleaseOptions) { comma.Add($"{nameof(GameRelease)}.{item} => {ReleaseEnumName(obj)}.{item}"); } comma.Add("_ => throw new ArgumentException()"); } } } } } } GenerateModGameCategoryRegistration(obj, fg); }
public override async Task GenerateInCommonMixin(ObjectGeneration obj, FileGeneration fg) { await base.GenerateInCommonMixin(obj, fg); var objData = obj.GetObjectData(); string gameReleaseStr; if (objData.GameReleaseOptions == null) { gameReleaseStr = $"{nameof(GameRelease)}.{obj.GetObjectData().GameCategory}"; } else { gameReleaseStr = $"item.GameRelease"; } if (obj.GetObjectType() != ObjectType.Mod) { return; } using (var args = new FunctionWrapper(fg, $"public static IGroupGetter<T> {nameof(IModGetter.GetTopLevelGroup)}<T>")) { args.Wheres.Add($"where T : {nameof(IMajorRecordGetter)}"); args.Add($"this {obj.Interface(getter: true)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return (IGroupGetter<T>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup")) { args.AddPassArg("obj"); args.Add("type: typeof(T)"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static IGroupGetter {nameof(IModGetter.GetTopLevelGroup)}")) { args.Add($"this {obj.Interface(getter: true)} obj"); args.Add("Type type"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return (IGroupGetter){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup")) { args.AddPassArg("obj"); args.AddPassArg("type"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static IGroup<T> {nameof(IMod.GetTopLevelGroup)}<T>")) { args.Wheres.Add($"where T : {nameof(IMajorRecord)}"); args.Add($"this {obj.Interface(getter: false)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return (IGroup<T>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup")) { args.AddPassArg("obj"); args.Add("type: typeof(T)"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static IGroup {nameof(IModGetter.GetTopLevelGroup)}")) { args.Add($"this {obj.Interface(getter: false)} obj"); args.Add("Type type"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return (IGroup){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup")) { args.AddPassArg("obj"); args.AddPassArg("type"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static void WriteToBinaryParallel")) { args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item"); args.Add($"Stream stream"); args.Add($"{nameof(BinaryWriteParameters)}? param = null"); args.Add($"{nameof(ParallelWriteParameters)}? parallelParam = null"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel")) { args.AddPassArg("item"); args.AddPassArg("stream"); args.Add($"parallelParam: parallelParam ?? {nameof(ParallelWriteParameters)}.{nameof(ParallelWriteParameters.Default)}"); args.Add($"param: param ?? {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)}"); args.Add("modKey: item.ModKey"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static void WriteToBinaryParallel")) { args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item"); args.Add($"string path"); args.Add($"{nameof(BinaryWriteParameters)}? param = null"); args.Add($"{nameof(ParallelWriteParameters)}? parallelParam = null"); args.Add($"{nameof(IFileSystem)}? fileSystem = null"); } using (new BraceWrapper(fg)) { fg.AppendLine($"param ??= {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)};"); fg.AppendLine($"parallelParam ??= {nameof(ParallelWriteParameters)}.{nameof(ParallelWriteParameters.Default)};"); using (var args = new ArgsWrapper(fg, $"var modKey = param.{nameof(BinaryWriteParameters.RunMasterMatch)}")) { args.Add("mod: item"); args.AddPassArg("path"); } if (obj.GetObjectData().UsesStringFiles) { fg.AppendLine($"param.StringsWriter ??= EnumExt.HasFlag((int)item.ModHeader.Flags, (int)ModHeaderCommonFlag.Localized) ? new StringsWriter({gameReleaseStr}, modKey, Path.Combine(Path.GetDirectoryName(path)!, \"Strings\"), {nameof(MutagenEncodingProvider)}.{nameof(MutagenEncodingProvider.Instance)}) : null;"); fg.AppendLine("bool disposeStrings = param.StringsWriter != null;"); } fg.AppendLine("using (var stream = fileSystem.GetOrDefault().FileStream.Create(path, FileMode.Create, FileAccess.Write))"); using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel")) { args.AddPassArg("item"); args.AddPassArg("stream"); args.AddPassArg("parallelParam"); args.Add($"param: param"); args.AddPassArg("modKey"); } } if (obj.GetObjectData().UsesStringFiles) { fg.AppendLine("if (disposeStrings)"); using (new BraceWrapper(fg)) { fg.AppendLine("param.StringsWriter?.Dispose();"); } } } fg.AppendLine(); }
private void GenerateWriteParallel(ObjectGeneration obj, FileGeneration fg) { LoquiType groupInstance = null; LoquiType listGroupInstance = null; var objData = obj.GetObjectData(); fg.AppendLine("const int CutCount = 100;"); using (var args = new FunctionWrapper(fg, "public static void WriteParallel")) { args.Add($"{obj.Interface(getter: true, internalInterface: false)} item"); args.Add($"Stream stream"); args.Add($"{nameof(BinaryWriteParameters)} param"); args.Add($"ModKey modKey"); } using (new BraceWrapper(fg)) { fg.AppendLine($"var masterRefs = UtilityTranslation.ConstructWriteMasters(item, param);"); fg.AppendLine($"var bundle = new {nameof(WritingBundle)}({nameof(GameConstants)}.{obj.GetObjectData().GameMode});"); fg.AppendLine($"bundle.{nameof(WritingBundle.MasterReferences)} = masterRefs;"); using (var args = new ArgsWrapper(fg, $"{obj.ObjectName}BinaryWriteTranslation.WriteModHeader")) { args.Add("item"); args.Add($"new MutagenWriter(stream, bundle)"); args.Add("modKey"); } int groupCount = obj.IterateFields() .Select(f => f as LoquiType) .Where(l => l != null) .Where(l => l.TargetObjectGeneration?.GetObjectData().ObjectType == ObjectType.Group) .Count(); fg.AppendLine($"Stream[] outputStreams = new Stream[{groupCount}];"); fg.AppendLine($"List<Action> toDo = new List<Action>();"); int i = 0; foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration?.GetObjectData().ObjectType != ObjectType.Group) { continue; } if (loqui.TargetObjectGeneration.Name == "ListGroup") { listGroupInstance = loqui; } else { groupInstance = loqui; } if (loqui.GetGroupTarget().GetObjectData().CustomBinaryEnd == CustomEnd.Off && loqui.TargetObjectGeneration.Name != "ListGroup") { fg.AppendLine($"toDo.Add(() => WriteGroupParallel(item.{field.Name}, masterRefs, {i}, outputStreams{(objData.UsesStringFiles ? ", param.StringsWriter" : null)}));"); } else { fg.AppendLine($"toDo.Add(() => Write{field.Name}Parallel(item.{field.Name}, masterRefs, {i}, outputStreams));"); } i++; } fg.AppendLine("Parallel.Invoke(toDo.ToArray());"); using (var args = new ArgsWrapper(fg, $"{nameof(UtilityTranslation)}.{nameof(UtilityTranslation.CompileStreamsInto)}")) { args.Add("outputStreams.NotNull()"); args.Add("stream"); } } fg.AppendLine(); if (groupInstance != null) { using (var args = new FunctionWrapper(fg, $"public static void WriteGroupParallel<T>")) { args.Add("IGroupGetter<T> group"); args.Add($"{nameof(MasterReferenceReader)} masters"); args.Add("int targetIndex"); args.Add("Stream[] streamDepositArray"); if (objData.UsesStringFiles) { args.Add($"{nameof(StringsWriter)}? stringsWriter"); } args.Wheres.AddRange(groupInstance.TargetObjectGeneration.GenerateWhereClauses(LoquiInterfaceType.IGetter, groupInstance.TargetObjectGeneration.Generics)); } using (new BraceWrapper(fg)) { fg.AppendLine("if (group.RecordCache.Count == 0) return;"); fg.AppendLine($"var cuts = group.Records.Cut(CutCount).ToArray();"); fg.AppendLine($"Stream[] subStreams = new Stream[cuts.Length + 1];"); fg.AppendLine($"byte[] groupBytes = new byte[{nameof(GameConstants)}.{obj.GetObjectData().GameMode}.GroupConstants.HeaderLength];"); fg.AppendLine($"BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);"); fg.AppendLine($"var groupByteStream = new MemoryStream(groupBytes);"); fg.AppendLine($"var bundle = new {nameof(WritingBundle)}({nameof(GameConstants)}.{obj.GetObjectData().GameMode})"); using (var prop = new PropertyCtorWrapper(fg)) { prop.Add($"{nameof(WritingBundle.MasterReferences)} = masters"); if (objData.UsesStringFiles) { prop.Add($"{nameof(WritingBundle.StringsWriter)} = stringsWriter"); } } fg.AppendLine($"using (var stream = new MutagenWriter(groupByteStream, {nameof(GameConstants)}.{obj.GetObjectData().GameMode}, dispose: false))"); using (new BraceWrapper(fg)) { fg.AppendLine($"stream.Position += 8;"); fg.AppendLine($"GroupBinaryWriteTranslation.WriteEmbedded<T>(group, stream);"); } fg.AppendLine($"subStreams[0] = groupByteStream;"); fg.AppendLine($"Parallel.ForEach(cuts, (cutItems, state, counter) =>"); using (new BraceWrapper(fg) { AppendSemicolon = true, AppendParenthesis = true }) { fg.AppendLine($"{nameof(MemoryTributary)} trib = new {nameof(MemoryTributary)}();"); fg.AppendLine($"using (var stream = new MutagenWriter(trib, bundle, dispose: false))"); using (new BraceWrapper(fg)) { fg.AppendLine($"foreach (var item in cutItems)"); using (new BraceWrapper(fg)) { fg.AppendLine($"item.WriteToBinary(stream);"); } } fg.AppendLine($"subStreams[(int)counter + 1] = trib;"); } fg.AppendLine($"UtilityTranslation.CompileSetGroupLength(subStreams, groupBytes);"); fg.AppendLine($"streamDepositArray[targetIndex] = new CompositeReadStream(subStreams, resetPositions: true);"); } fg.AppendLine(); } }
public override async Task GenerateInCommonMixin(ObjectGeneration obj, FileGeneration fg) { await base.GenerateInCommonMixin(obj, fg); if (obj.GetObjectType() != ObjectType.Mod) { return; } using (var args = new FunctionWrapper(fg, $"public static IReadOnlyCache<T, FormKey> {nameof(IModGetter.GetTopLevelGroupGetter)}<T>")) { args.Wheres.Add($"where T : {nameof(IMajorRecordCommonGetter)}"); args.Add($"this {obj.Interface(getter: true)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return (IReadOnlyCache<T, FormKey>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup<T>")) { args.AddPassArg("obj"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, "public static ICache<T, FormKey> GetGroup<T>")) { args.Wheres.Add($"where T : {nameof(IMajorRecordCommon)}"); args.Add($"this {obj.Interface(getter: false)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return (ICache<T, FormKey>){obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.GetGroup<T>")) { args.AddPassArg("obj"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static void WriteToBinaryParallel")) { args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item"); args.Add($"Stream stream"); args.Add($"{nameof(BinaryWriteParameters)}? param = null"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel")) { args.AddPassArg("item"); args.AddPassArg("stream"); args.Add($"param: param ?? {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)}"); args.Add("modKey: item.ModKey"); } } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public static void WriteToBinaryParallel")) { args.Add($"this {obj.Interface(getter: true, internalInterface: false)} item"); args.Add($"string path"); args.Add($"{nameof(BinaryWriteParameters)}? param = null"); } using (new BraceWrapper(fg)) { fg.AppendLine($"param ??= {nameof(BinaryWriteParameters)}.{nameof(BinaryWriteParameters.Default)};"); using (var args = new ArgsWrapper(fg, $"var modKey = param.{nameof(BinaryWriteParameters.RunMasterMatch)}")) { args.Add("mod: item"); args.AddPassArg("path"); } if (obj.GetObjectData().UsesStringFiles) { fg.AppendLine("bool disposeStrings = param.StringsWriter == null;"); fg.AppendLine("param.StringsWriter ??= EnumExt.HasFlag((int)item.ModHeader.Flags, (int)ModHeaderCommonFlag.Localized) ? new StringsWriter(modKey, Path.Combine(Path.GetDirectoryName(path)!, \"Strings\")) : null;"); } fg.AppendLine("using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write))"); using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)}.WriteParallel")) { args.AddPassArg("item"); args.AddPassArg("stream"); args.Add($"param: param"); args.AddPassArg("modKey"); } } if (obj.GetObjectData().UsesStringFiles) { fg.AppendLine("if (disposeStrings)"); using (new BraceWrapper(fg)) { fg.AppendLine("param.StringsWriter?.Dispose();"); } } } fg.AppendLine(); }
public override void GenerateWriteToNode(ObjectGeneration obj, FileGeneration fg) { using (var args = new FunctionWrapper(fg, $"public static void WriteToNode{ModuleNickname}{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.IGetter, defs: obj.Generics)); args.Add($"{obj.Interface(internalInterface: true, getter: true)} item"); args.Add($"XElement {XmlTranslationModule.XElementLine.GetParameterName(obj)}"); args.Add($"ErrorMaskBuilder? errorMask"); args.Add($"{nameof(TranslationCrystal)}? translationMask"); } using (new BraceWrapper(fg)) { if (obj.HasLoquiBaseObject) { using (var args = new ArgsWrapper(fg, $"{this.TranslationWriteClass(obj.BaseClass)}.WriteToNode{ModuleNickname}")) { args.Add($"item: item"); args.Add($"{XmlTranslationModule.XElementLine.GetParameterName(obj)}: {XmlTranslationModule.XElementLine.GetParameterName(obj)}"); args.Add($"errorMask: errorMask"); args.Add($"translationMask: translationMask"); } } void generateNormal(XmlTranslationGeneration generator, TypeGeneration field) { if (!generator.ShouldGenerateWrite(field)) { return; } List <string> conditions = new List <string>(); if (field.Nullable) { conditions.Add($"{field.NullableAccessor(getter: true, accessor: Accessor.FromType(field, "item"))}"); } if (this.TranslationMaskParameter) { conditions.Add(field.GetTranslationIfAccessor("translationMask")); } if (conditions.Count > 0) { using (var args = new IfWrapper(fg, ANDs: true)) { foreach (var item in conditions) { args.Add(item); } } } using (new BraceWrapper(fg, doIt: conditions.Count > 0)) { var maskType = this.Gen.MaskModule.GetMaskModule(field.GetType()).GetErrorMaskTypeStr(field); generator.GenerateWrite( fg: fg, objGen: obj, typeGen: field, writerAccessor: $"{XmlTranslationModule.XElementLine.GetParameterName(obj)}", itemAccessor: Accessor.FromType(field, "item"), errorMaskAccessor: $"errorMask", translationMaskAccessor: "translationMask", nameAccessor: $"nameof(item.{field.Name})"); } } foreach (var field in obj.IterateFields(expandSets: SetMarkerType.ExpandSets.FalseAndInclude, nonIntegrated: true)) { if (!this.TryGetTypeGeneration(field.GetType(), out var generator)) { if (!field.IntegrateField) { continue; } throw new ArgumentException("Unsupported type generator: " + field); } if (field is DataType dataType) { if (dataType.Nullable) { fg.AppendLine($"if (item.{dataType.StateName}.HasFlag({obj.Name}.{dataType.EnumName}.Has))"); } using (new BraceWrapper(fg, doIt: dataType.Nullable)) { bool isInRange = false; int encounteredBreakIndex = 0; foreach (var subField in dataType.IterateFieldsWithMeta()) { if (!this.TryGetTypeGeneration(subField.Field.GetType(), out var subGenerator)) { throw new ArgumentException("Unsupported type generator: " + subField.Field); } var subData = subField.Field.GetFieldData(); if (!subGenerator.ShouldGenerateCopyIn(subField.Field)) { continue; } if (subField.BreakIndex != -1) { fg.AppendLine($"if (!item.{dataType.StateName}.HasFlag({obj.Name}.{dataType.EnumName}.Break{subField.BreakIndex}))"); fg.AppendLine("{"); fg.Depth++; encounteredBreakIndex++; } if (subField.Range != null && !isInRange) { isInRange = true; fg.AppendLine($"if (item.{dataType.StateName}.HasFlag({obj.Name}.{dataType.EnumName}.Range{subField.RangeIndex}))"); fg.AppendLine("{"); fg.Depth++; } if (subField.Range == null && isInRange) { isInRange = false; fg.Depth--; fg.AppendLine("}"); } generateNormal(subGenerator, subField.Field); } for (int i = 0; i < encounteredBreakIndex; i++) { fg.Depth--; fg.AppendLine("}"); if (i == encounteredBreakIndex - 1) { fg.AppendLine("else"); using (new BraceWrapper(fg)) { fg.AppendLine($"node.Add(new XElement(\"Has{dataType.EnumName}\"));"); } } } } } else { generateNormal(generator, field); } } } fg.AppendLine(); }
public override async Task GenerateInCommon(ObjectGeneration obj, FileGeneration fg, MaskTypeSet maskTypes) { if (!maskTypes.Applicable(LoquiInterfaceType.ISetter, CommonGenerics.Class)) { return; } var accessor = new Accessor("obj"); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } var overrideStr = await obj.FunctionOverride(async c => await MajorRecordModule.HasMajorRecords(c, includeBaseClass : false, includeSelf : true) != Case.No); using (var args = new FunctionWrapper(fg, $"public{overrideStr}void Remove")) { args.Add($"{obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"HashSet<{nameof(FormKey)}> keys"); } using (new BraceWrapper(fg)) { var fgCount = fg.Count; foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { fg.AppendLine($"base.Remove(obj, keys);"); break; } } foreach (var field in obj.IterateFields()) { switch (field) { case LoquiType _: case ContainerType _: case DictType _: break; default: continue; } FileGeneration fieldFg = new FileGeneration(); if (field is LoquiType loqui) { var fieldAccessor = $"{accessor}.{loqui.Name}"; if (await MajorRecordModule.HasMajorRecords(loqui.TargetObjectGeneration, includeBaseClass: true, includeSelf: false) != Case.No) { fg.AppendLine($"{fieldAccessor}{loqui.NullChar}.Remove(keys);"); } var isMajorRecord = loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord(); if (isMajorRecord) { fg.AppendLine($"if ({(loqui.Nullable ? $"{fieldAccessor} != null && " : string.Empty)}keys.Contains({fieldAccessor}.FormKey))"); using (new BraceWrapper(fg)) { fg.AppendLine($"{fieldAccessor} = null;"); } } } else if (field is ContainerType cont) { if (!(cont.SubTypeGeneration is LoquiType contLoqui)) { continue; } var isMajorRecord = await contLoqui.IsMajorRecord(); if (isMajorRecord) { fg.AppendLine($"{accessor}.{field.Name}.Remove(keys);"); } if (await MajorRecordModule.HasMajorRecords(contLoqui, includeBaseClass: true, includeSelf: false) != Case.No) { fg.AppendLine($"{accessor}.{field.Name}.ForEach(i => i.Remove(keys));"); } if (contLoqui.TargetObjectGeneration?.IsListGroup() ?? false) { fg.AppendLine($"{accessor}.{field.Name}.RemoveWhere(i => i.{contLoqui.TargetObjectGeneration.Fields.FirstOrDefault(f => f is ContainerType).Name}.Count == 0);"); } } else if (field is DictType dict) { if (dict.Mode != DictMode.KeyedValue) { continue; } if (!(dict.ValueTypeGen is LoquiType dictLoqui)) { continue; } var isMajorRecord = dictLoqui.TargetObjectGeneration != null && await dictLoqui.TargetObjectGeneration.IsMajorRecord(); if (isMajorRecord || await MajorRecordModule.HasMajorRecords(dictLoqui, includeBaseClass: true) != Case.No) { switch (await MajorRecordModule.HasMajorRecords(dictLoqui, includeBaseClass: true)) { case Case.Yes: case Case.Maybe: fg.AppendLine($"{accessor}.{field.Name}.Remove(keys);"); break; case Case.No: default: break; } } } if (fieldFg.Count > 0) { if (field.Nullable) { fg.AppendLine($"if ({field.NullableAccessor(getter: true, Accessor.FromType(field, accessor.ToString()))})"); } using (new BraceWrapper(fg, doIt: field.Nullable)) { fg.AppendLines(fieldFg); } } } } fg.AppendLine(); // Generate base overrides foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { using (var args = new FunctionWrapper(fg, $"public override void Remove")) { args.Add($"{baseClass.Interface(getter: false)} obj"); args.Add($"HashSet<{nameof(FormKey)}> keys"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, "Remove")) { args.Add($"({obj.Interface(getter: false)})obj"); args.AddPassArg("keys"); } } fg.AppendLine(); } } using (var args = new FunctionWrapper(fg, $"public{overrideStr}void Remove")) { args.Add($"{obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"HashSet<{nameof(FormKey)}> keys"); args.Add($"Type type"); args.Add($"bool throwIfUnknown"); } using (new BraceWrapper(fg)) { var fgCount = fg.Count; foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { fg.AppendLine("base.Remove(obj, type, keys);"); break; } } fg.AppendLine("switch (type.Name)"); using (new BraceWrapper(fg)) { var gameCategory = obj.GetObjectData().GameCategory; fg.AppendLine($"case \"{nameof(IMajorRecordCommon)}\":"); fg.AppendLine($"case \"{nameof(IMajorRecord)}\":"); fg.AppendLine($"case \"{nameof(MajorRecord)}\":"); if (gameCategory != null) { fg.AppendLine($"case \"I{gameCategory}MajorRecord\":"); fg.AppendLine($"case \"{gameCategory}MajorRecord\":"); } fg.AppendLine($"case \"{nameof(IMajorRecordGetter)}\":"); fg.AppendLine($"case \"{nameof(IMajorRecordCommonGetter)}\":"); if (gameCategory != null) { fg.AppendLine($"case \"I{gameCategory}MajorRecordGetter\":"); } using (new DepthWrapper(fg)) { fg.AppendLine($"if (!{obj.RegistrationName}.SetterType.IsAssignableFrom(obj.GetType())) return;"); fg.AppendLine("this.Remove(obj, keys);"); fg.AppendLine("break;"); } Dictionary <object, FileGeneration> generationDict = new Dictionary <object, FileGeneration>(); foreach (var field in obj.IterateFields()) { LoquiType targetLoqui; FileGeneration fieldGen; if (field is LoquiType loqui) { if (loqui.TargetObjectGeneration.IsListGroup()) { continue; } var isMajorRecord = loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord(); if (!isMajorRecord && await MajorRecordModule.HasMajorRecords(loqui, includeBaseClass: true) == Case.No) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() == ObjectType.Group) { fieldGen = generationDict.GetOrAdd(loqui.GetGroupTarget()); } else { fieldGen = generationDict.GetOrAdd(((object)loqui?.TargetObjectGeneration) ?? loqui); } targetLoqui = loqui; } else if (field is ContainerType cont) { if (!(cont.SubTypeGeneration is LoquiType contLoqui)) { continue; } if (contLoqui.RefType == LoquiType.LoquiRefType.Generic) { fieldGen = generationDict.GetOrAdd("default:"); } else { fieldGen = generationDict.GetOrAdd(((object)contLoqui?.TargetObjectGeneration) ?? contLoqui); } targetLoqui = contLoqui; } else if (field is DictType dict) { if (dict.Mode != DictMode.KeyedValue) { continue; } if (!(dict.ValueTypeGen is LoquiType dictLoqui)) { continue; } if (dictLoqui.RefType == LoquiType.LoquiRefType.Generic) { fieldGen = generationDict.GetOrAdd("default:"); } else { fieldGen = generationDict.GetOrAdd(((object)dictLoqui?.TargetObjectGeneration) ?? dictLoqui); } targetLoqui = dictLoqui; } else { continue; } bool applicable = false; switch (targetLoqui.RefType) { case LoquiType.LoquiRefType.Direct: applicable = await targetLoqui.TargetObjectGeneration.IsMajorRecord(); break; case LoquiType.LoquiRefType.Interface: applicable = true; break; case LoquiType.LoquiRefType.Generic: default: break; } await ApplyRemovalLines(field, fieldGen, accessor, removeSelf : applicable); } bool doAdditionlDeepLogic = obj.Name != "ListGroup"; if (doAdditionlDeepLogic) { LinkInterfaceModule.ObjectMappings.TryGetValue(obj.ProtoGen.Protocol, out var interfs); var deepRecordMapping = await MajorRecordModule.FindDeepRecords(obj); foreach (var deepRec in deepRecordMapping) { FileGeneration deepFg = generationDict.GetOrAdd(deepRec.Key); foreach (var field in deepRec.Value) { var remSelf = false; switch (field) { case ContainerType cont: if (cont.SubTypeGeneration is LoquiType loqui) { switch (loqui.RefType) { case LoquiType.LoquiRefType.Direct: remSelf = loqui.TargetObjectGeneration == deepRec.Key; break; case LoquiType.LoquiRefType.Interface: if (interfs.TryGetValue(loqui.SetterInterface, out var objs)) { remSelf = objs.Contains(deepRec.Key); } break; case LoquiType.LoquiRefType.Generic: default: break; } } break; default: break; } remSelf &= await deepRec.Key.IsMajorRecord(); await ApplyRemovalLines(field, deepFg, accessor, obj : deepRec.Key, removeSelf : remSelf); } } // Generate for major record marker interfaces foreach (var interf in interfs.EmptyIfNull()) { FileGeneration subFg = new FileGeneration(); HashSet <ObjectGeneration> passedObjects = new HashSet <ObjectGeneration>(); HashSet <TypeGeneration> deepObjects = new HashSet <TypeGeneration>(); foreach (var subObj in interf.Value) { var grup = obj.Fields .WhereCastable <TypeGeneration, GroupType>() .Where(g => g.GetGroupTarget() == subObj) .FirstOrDefault(); if (grup != null) { subFg.AppendLine($"Remove({accessor}, keys, typeof({grup.GetGroupTarget().Interface(getter: true)}), throwIfUnknown: throwIfUnknown);"); passedObjects.Add(grup.GetGroupTarget()); } else if (deepRecordMapping.TryGetValue(subObj, out var deepRec)) { foreach (var field in deepRec) { deepObjects.Add(field); } } } foreach (var deepObj in deepObjects) { bool remSelf = false; switch (deepObj) { case ContainerType cont: if (cont.SubTypeGeneration is LoquiType loqui) { remSelf = loqui.RefType == LoquiType.LoquiRefType.Interface && loqui.Interface(getter: false) == interf.Key; } break; default: break; } await ApplyRemovalLines(deepObj, subFg, accessor, blackList : passedObjects, removeSelf : remSelf); } if (!subFg.Empty) { var genFg = generationDict.GetOrAdd(new InterfInstr() { Interf = interf.Key }); genFg.AppendLines(subFg); } } foreach (var kv in generationDict) { switch (kv.Key) { case LoquiType loqui: if (loqui.RefType == LoquiType.LoquiRefType.Direct) { fg.AppendLine($"case \"{loqui.Interface(getter: true)}\":"); fg.AppendLine($"case \"{loqui.Interface(getter: false)}\":"); if (loqui.HasInternalGetInterface) { fg.AppendLine($"case \"{loqui.Interface(getter: true, internalInterface: true)}\":"); } if (loqui.HasInternalSetInterface) { fg.AppendLine($"case \"{loqui.Interface(getter: false, internalInterface: true)}\":"); } } else { continue; } break; case ObjectGeneration targetObj: fg.AppendLine($"case \"{targetObj.ObjectName}\":"); fg.AppendLine($"case \"{targetObj.Interface(getter: true)}\":"); fg.AppendLine($"case \"{targetObj.Interface(getter: false)}\":"); if (targetObj.HasInternalGetInterface) { fg.AppendLine($"case \"{targetObj.Interface(getter: true, internalInterface: true)}\":"); } if (targetObj.HasInternalSetInterface) { fg.AppendLine($"case \"{targetObj.Interface(getter: false, internalInterface: true)}\":"); } break; case InterfInstr interf: fg.AppendLine($"case \"{interf.Interf}\":"); fg.AppendLine($"case \"{interf.Interf}Getter\":"); break; case string str: if (str != "default:") { throw new NotImplementedException(); } continue; default: throw new NotImplementedException(); } using (new DepthWrapper(fg)) { fg.AppendLines(kv.Value); fg.AppendLine("break;"); } } } fg.AppendLine("default:"); using (new DepthWrapper(fg)) { if (generationDict.TryGetValue("default:", out var gen)) { fg.AppendLines(gen); fg.AppendLine("break;"); } else { fg.AppendLine("if (throwIfUnknown)"); using (new BraceWrapper(fg)) { fg.AppendLine("throw new ArgumentException($\"Unknown major record type: {type}\");"); } fg.AppendLine($"else"); using (new BraceWrapper(fg)) { fg.AppendLine("break;"); } } } } } fg.AppendLine(); // Generate base overrides foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { using (var args = new FunctionWrapper(fg, $"public override void Remove")) { args.Add($"{baseClass.Interface(getter: false)} obj"); args.Add($"HashSet<{nameof(FormKey)}> keys"); args.Add($"Type type"); args.Add($"bool throwIfUnknown"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, "Remove")) { args.Add($"({obj.Interface(getter: false)})obj"); args.AddPassArg("keys"); args.AddPassArg("type"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); } } }
public virtual void GenerateWriteToNode(ObjectGeneration obj, StructuredStringBuilder sb) { using (var args = new Function(sb, $"public static void WriteToNode{ModuleNickname}{obj.GetGenericTypes(MaskType.Normal)}")) { args.Add($"{obj.Interface(internalInterface: true, getter: true)} item"); args.Add($"XElement {XElementLine.GetParameterName(obj, Context.Backend)}"); args.Add($"ErrorMaskBuilder? errorMask"); args.Add($"{nameof(TranslationCrystal)}? translationMask"); } using (sb.CurlyBrace()) { if (obj.HasLoquiBaseObject) { using (var args = sb.Call( $"{TranslationWriteClass(obj.BaseClass)}.WriteToNode{ModuleNickname}")) { args.Add($"item: item"); args.Add($"{XElementLine.GetParameterName(obj, Context.Backend)}: {XElementLine.GetParameterName(obj, Context.Backend)}"); args.Add($"errorMask: errorMask"); args.Add($"translationMask: translationMask"); } } foreach (var field in obj.IterateFieldIndices()) { if (!TryGetTypeGeneration(field.Field.GetType(), out var generator)) { throw new ArgumentException("Unsupported type generator: " + field.Field); } if (!generator.ShouldGenerateWrite(field.Field)) { continue; } List <string> conditions = new List <string>(); if (field.Field.Nullable) { conditions.Add($"{field.Field.NullableAccessor(getter: true, accessor: Accessor.FromType(field.Field, "item"))}"); } if (TranslationMaskParameter) { conditions.Add(field.Field.GetTranslationIfAccessor("translationMask")); } if (conditions.Count > 0) { using (var args = sb.If(ands: true)) { foreach (var item in conditions) { args.Add(item); } } } using (sb.CurlyBrace(doIt: conditions.Count > 0)) { var maskType = Gen.MaskModule.GetMaskModule(field.Field.GetType()).GetErrorMaskTypeStr(field.Field); generator.GenerateWrite( sb: sb, objGen: obj, typeGen: field.Field, writerAccessor: $"{XElementLine.GetParameterName(obj, Context.Backend)}", itemAccessor: Accessor.FromType(field.Field, "item"), errorMaskAccessor: $"errorMask", translationMaskAccessor: "translationMask", nameAccessor: $"nameof(item.{field.Field.Name})"); } } } sb.AppendLine(); }
protected virtual void FillPublicElement(ObjectGeneration obj, StructuredStringBuilder sb) { using (var args = new Function(sb, $"public static void FillPublicElement{ModuleNickname}")) { args.Add($"{obj.Interface(getter: false)} item"); args.Add($"XElement {XElementLine.GetParameterName(obj, Context.Backend)}"); args.Add("string name"); args.Add($"ErrorMaskBuilder? errorMask"); args.Add($"{nameof(TranslationCrystal)}? translationMask"); } using (sb.CurlyBrace()) { sb.AppendLine("switch (name)"); using (sb.CurlyBrace()) { foreach (var field in obj.IterateFields()) { if (field.Derivative) { continue; } if (field.ReadOnly) { continue; } if (!TryGetTypeGeneration(field.GetType(), out var generator)) { throw new ArgumentException("Unsupported type generator: " + field); } sb.AppendLine($"case \"{field.Name}\":"); using (sb.IncreaseDepth()) { if (generator.ShouldGenerateCopyIn(field)) { List <string> conditions = new List <string>(); if (TranslationMaskParameter) { conditions.Add(field.GetTranslationIfAccessor("translationMask")); } if (conditions.Count > 0) { using (var args = sb.If(ands: true)) { foreach (var item in conditions) { args.Add(item); } } } using (sb.CurlyBrace(doIt: conditions.Count > 0)) { generator.GenerateCopyIn( sb: sb, objGen: obj, typeGen: field, nodeAccessor: XElementLine.GetParameterName(obj, Context.Backend).Result, itemAccessor: Accessor.FromType(field, "item"), translationMaskAccessor: "translationMask", errorMaskAccessor: $"errorMask"); } } sb.AppendLine("break;"); } } sb.AppendLine("default:"); using (sb.IncreaseDepth()) { if (obj.HasLoquiBaseObject) { using (var args = sb.Call( $"{obj.BaseClass.CommonClassName(LoquiInterfaceType.ISetter)}.FillPublicElement{ModuleNickname}{obj.GetBaseMask_GenericTypes(MaskType.Error)}")) { args.Add("item: item"); args.Add($"{XElementLine.GetParameterName(obj, Context.Backend)}: {XElementLine.GetParameterName(obj, Context.Backend)}"); args.Add("name: name"); args.Add("errorMask: errorMask"); if (TranslationMaskParameter) { args.Add($"translationMask: translationMask"); } } } sb.AppendLine("break;"); } } } sb.AppendLine(); }
public override async Task PostLoad(ObjectGeneration obj) { await base.PostLoad(obj); if (obj.Abstract || !await obj.IsMajorRecord()) { return; } obj.Interfaces.Add(LoquiInterfaceDefinitionType.IGetter, $"IMapsToGetter<{obj.Interface(getter: true, internalInterface: false)}>"); }
public override async Task GenerateInCommonMixin(ObjectGeneration obj, FileGeneration fg) { if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } var needsCatch = obj.GetObjectType() == ObjectType.Mod; string catchLine = needsCatch ? ".Catch(e => throw RecordException.Enrich(e, obj.ModKey))" : string.Empty; string enderSemi = needsCatch ? string.Empty : ";"; fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static IEnumerable<{nameof(IMajorRecordCommonGetter)}> EnumerateMajorRecords{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.IGetter, obj.Generics)); args.Add($"this {obj.Interface(getter: true, internalInterface: true)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return {obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class)}.EnumerateMajorRecords", suffixLine: catchLine)) { args.AddPassArg("obj"); } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static IEnumerable<TMajor> EnumerateMajorRecords{obj.GetGenericTypes(MaskType.Normal, "TMajor")}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.IGetter, obj.Generics)); args.Wheres.Add($"where TMajor : class, IMajorRecordCommonGetter"); args.Add($"this {obj.Interface(getter: true, internalInterface: true)} obj"); args.Add($"bool throwIfUnknown = true"); } using (new BraceWrapper(fg)) { using (var args = new FunctionWrapper(fg, $"return {obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class)}.EnumerateMajorRecords")) { args.AddPassArg("obj"); args.Add("type: typeof(TMajor)"); args.AddPassArg("throwIfUnknown"); } using (new DepthWrapper(fg)) { fg.AppendLine($".Select(m => (TMajor)m){enderSemi}"); if (needsCatch) { fg.AppendLine($"{catchLine};"); } } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static IEnumerable<{nameof(IMajorRecordCommonGetter)}> EnumerateMajorRecords{obj.GetGenericTypes(MaskType.Normal)}")) { args.Add($"this {obj.Interface(getter: true, internalInterface: true)} obj"); args.Add($"Type type"); args.Add($"bool throwIfUnknown = true"); args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.IGetter, obj.Generics)); } using (new BraceWrapper(fg)) { using (var args = new FunctionWrapper(fg, $"return {obj.CommonClassInstance("obj", LoquiInterfaceType.IGetter, CommonGenerics.Class)}.EnumerateMajorRecords")) { args.AddPassArg("obj"); args.AddPassArg("type"); args.AddPassArg("throwIfUnknown"); } using (new DepthWrapper(fg)) { fg.AppendLine($".Select(m => ({nameof(IMajorRecordCommonGetter)})m){enderSemi}"); if (needsCatch) { fg.AppendLine($"{catchLine};"); } } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static IEnumerable<{nameof(IMajorRecordCommon)}> EnumerateMajorRecords{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return {obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.EnumerateMajorRecords", suffixLine: catchLine)) { args.AddPassArg("obj"); } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static IEnumerable<TMajor> EnumerateMajorRecords{obj.GetGenericTypes(MaskType.Normal, "TMajor")}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Wheres.Add($"where TMajor : class, IMajorRecordCommon"); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); } using (new BraceWrapper(fg)) { using (var args = new FunctionWrapper(fg, $"return {obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.EnumerateMajorRecords")) { args.AddPassArg("obj"); args.Add("type: typeof(TMajor)"); args.Add("throwIfUnknown: true"); } using (new DepthWrapper(fg)) { fg.AppendLine($".Select(m => (TMajor)m){enderSemi}"); if (needsCatch) { fg.AppendLine($"{catchLine};"); } } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static IEnumerable<{nameof(IMajorRecordCommon)}> EnumerateMajorRecords{obj.GetGenericTypes(MaskType.Normal)}")) { args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"Type? type"); args.Add($"bool throwIfUnknown = true"); args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); } using (new BraceWrapper(fg)) { using (var args = new FunctionWrapper(fg, $"return {obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.EnumeratePotentiallyTypedMajorRecords")) { args.AddPassArg("obj"); args.AddPassArg("type"); args.AddPassArg("throwIfUnknown"); } using (new DepthWrapper(fg)) { fg.AppendLine($".Select(m => ({nameof(IMajorRecordCommon)})m){enderSemi}"); if (needsCatch) { fg.AppendLine($"{catchLine};"); } } } fg.AppendLine(); }
public override async Task GenerateInCommon(ObjectGeneration obj, FileGeneration fg, MaskTypeSet maskTypes) { bool getter = maskTypes.Applicable(LoquiInterfaceType.IGetter, CommonGenerics.Class); bool setter = maskTypes.Applicable(LoquiInterfaceType.ISetter, CommonGenerics.Class); if (!getter && !setter) { return; } var accessor = new Accessor("obj"); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } var overrideStr = await obj.FunctionOverride(async c => await MajorRecordModule.HasMajorRecords(c, includeBaseClass : false, includeSelf : true) != Case.No); using (var args = new FunctionWrapper(fg, $"public{overrideStr}IEnumerable<{nameof(IMajorRecordCommon)}{(getter ? "Getter" : null)}> EnumerateMajorRecords")) { args.Add($"{obj.Interface(getter: getter, internalInterface: true)} obj"); } using (new BraceWrapper(fg)) { if (setter) { fg.AppendLine($"foreach (var item in {obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class)}.Instance.EnumerateMajorRecords(obj))"); using (new BraceWrapper(fg)) { fg.AppendLine($"yield return (item as {nameof(IMajorRecordCommon)})!;"); } } else { var fgCount = fg.Count; foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { fg.AppendLine("foreach (var item in base.EnumerateMajorRecords(obj))"); using (new BraceWrapper(fg)) { fg.AppendLine("yield return item;"); } break; } } foreach (var field in obj.IterateFields()) { switch (field) { case LoquiType _: case ContainerType _: case DictType _: break; default: continue; } FileGeneration fieldFg = new FileGeneration(); if (field is LoquiType loqui) { var isMajorRecord = loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord(); if (isMajorRecord || await MajorRecordModule.HasMajorRecords(loqui, includeBaseClass: true) != Case.No) { var subFg = new FileGeneration(); var fieldAccessor = loqui.Nullable ? $"{loqui.Name}item" : $"{accessor}.{loqui.Name}"; await LoquiTypeHandler(subFg, fieldAccessor, loqui, generic : null, checkType : false); if (subFg.Count == 0) { continue; } if (loqui.Singleton || !loqui.Nullable) { fieldFg.AppendLines(subFg); } else { fieldFg.AppendLine($"if ({accessor}.{loqui.Name}.TryGet(out var {loqui.Name}item))"); using (new BraceWrapper(fieldFg)) { fieldFg.AppendLines(subFg); } } } } else if (field is ContainerType cont) { if (!(cont.SubTypeGeneration is LoquiType contLoqui)) { continue; } var isMajorRecord = contLoqui.TargetObjectGeneration != null && await contLoqui.TargetObjectGeneration.IsMajorRecord(); if (isMajorRecord || await MajorRecordModule.HasMajorRecords(contLoqui, includeBaseClass: true) != Case.No) { switch (await MajorRecordModule.HasMajorRecords(contLoqui, includeBaseClass: true)) { case Case.Yes: fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}{(field.Nullable ? ".EmptyIfNull()" : null)})"); using (new BraceWrapper(fieldFg)) { await LoquiTypeHandler(fieldFg, $"subItem", contLoqui, generic : null, checkType : false); } break; case Case.Maybe: fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}{(field.Nullable ? ".EmptyIfNull()" : null)}.WhereCastable<{contLoqui.TypeName(getter: false)}, {(getter ? nameof(IMajorRecordGetterEnumerable) : nameof(IMajorRecordEnumerable))}>())"); using (new BraceWrapper(fieldFg)) { await LoquiTypeHandler(fieldFg, $"subItem", contLoqui, generic : null, checkType : false); } break; case Case.No: default: break; } } } else if (field is DictType dict) { if (dict.Mode != DictMode.KeyedValue) { continue; } if (!(dict.ValueTypeGen is LoquiType dictLoqui)) { continue; } var isMajorRecord = dictLoqui.TargetObjectGeneration != null && await dictLoqui.TargetObjectGeneration.IsMajorRecord(); if (isMajorRecord || await MajorRecordModule.HasMajorRecords(dictLoqui, includeBaseClass: true) != Case.No) { switch (await MajorRecordModule.HasMajorRecords(dictLoqui, includeBaseClass: true)) { case Case.Yes: fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}.Items)"); using (new BraceWrapper(fieldFg)) { await LoquiTypeHandler(fieldFg, $"subItem", dictLoqui, generic : null, checkType : false); } break; case Case.Maybe: fieldFg.AppendLine($"foreach (var subItem in {accessor}.{field.Name}.Items.WhereCastable<{dictLoqui.TypeName(getter: false)}, {(getter ? nameof(IMajorRecordGetterEnumerable) : nameof(IMajorRecordEnumerable))}>())"); using (new BraceWrapper(fieldFg)) { await LoquiTypeHandler(fieldFg, $"subItem", dictLoqui, generic : null, checkType : false); } break; case Case.No: default: break; } } } if (fieldFg.Count > 0) { if (field.Nullable) { fg.AppendLine($"if ({field.NullableAccessor(getter: true, Accessor.FromType(field, accessor.ToString()))})"); } using (new BraceWrapper(fg, doIt: field.Nullable)) { fg.AppendLines(fieldFg); } } } if (fgCount == fg.Count) { fg.AppendLine("yield break;"); } } } fg.AppendLine(); // Generate base overrides foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { using (var args = new FunctionWrapper(fg, $"public override IEnumerable<{nameof(IMajorRecordCommon)}{(getter ? "Getter" : null)}> EnumerateMajorRecords")) { args.Add($"{baseClass.Interface(getter: getter)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, "EnumerateMajorRecords")) { args.Add($"({obj.Interface(getter: getter)})obj"); } } fg.AppendLine(); } } using (var args = new FunctionWrapper(fg, $"public{overrideStr}IEnumerable<{nameof(IMajorRecordCommonGetter)}> EnumeratePotentiallyTypedMajorRecords")) { args.Add($"{obj.Interface(getter: getter, internalInterface: true)} obj"); args.Add($"Type? type"); args.Add($"bool throwIfUnknown"); } using (new BraceWrapper(fg)) { fg.AppendLine("if (type == null) return EnumerateMajorRecords(obj);"); fg.AppendLine("return EnumerateMajorRecords(obj, type, throwIfUnknown);"); } fg.AppendLine(); using (var args = new FunctionWrapper(fg, $"public{overrideStr}IEnumerable<{nameof(IMajorRecordCommonGetter)}> EnumerateMajorRecords")) { args.Add($"{obj.Interface(getter: getter, internalInterface: true)} obj"); args.Add($"Type type"); args.Add($"bool throwIfUnknown"); } using (new BraceWrapper(fg)) { if (setter) { fg.AppendLine($"foreach (var item in {obj.CommonClass(LoquiInterfaceType.IGetter, CommonGenerics.Class)}.Instance.EnumerateMajorRecords(obj, type, throwIfUnknown))"); using (new BraceWrapper(fg)) { fg.AppendLine("yield return item;"); } } else { var fgCount = fg.Count; foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { fg.AppendLine("foreach (var item in base.EnumerateMajorRecords<TMajor>(obj))"); using (new BraceWrapper(fg)) { fg.AppendLine("yield return item;"); } break; } } fg.AppendLine("switch (type.Name)"); using (new BraceWrapper(fg)) { var gameCategory = obj.GetObjectData().GameCategory; fg.AppendLine($"case \"{nameof(IMajorRecordCommon)}\":"); fg.AppendLine($"case \"{nameof(IMajorRecord)}\":"); fg.AppendLine($"case \"{nameof(MajorRecord)}\":"); if (gameCategory != null) { fg.AppendLine($"case \"I{gameCategory}MajorRecord\":"); fg.AppendLine($"case \"{gameCategory}MajorRecord\":"); } using (new DepthWrapper(fg)) { fg.AppendLine($"if (!{obj.RegistrationName}.SetterType.IsAssignableFrom(obj.GetType())) yield break;"); fg.AppendLine("foreach (var item in this.EnumerateMajorRecords(obj))"); using (new BraceWrapper(fg)) { fg.AppendLine("yield return item;"); } fg.AppendLine("yield break;"); } fg.AppendLine($"case \"{nameof(IMajorRecordGetter)}\":"); fg.AppendLine($"case \"{nameof(IMajorRecordCommonGetter)}\":"); if (gameCategory != null) { fg.AppendLine($"case \"I{gameCategory}MajorRecordGetter\":"); } using (new DepthWrapper(fg)) { fg.AppendLine("foreach (var item in this.EnumerateMajorRecords(obj))"); using (new BraceWrapper(fg)) { fg.AppendLine("yield return item;"); } fg.AppendLine("yield break;"); } Dictionary <object, FileGeneration> generationDict = new Dictionary <object, FileGeneration>(); foreach (var field in obj.IterateFields()) { FileGeneration fieldGen; if (field is LoquiType loqui) { if (loqui.TargetObjectGeneration.IsListGroup()) { continue; } var isMajorRecord = loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord(); if (!isMajorRecord && await MajorRecordModule.HasMajorRecords(loqui, includeBaseClass: true) == Case.No) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() == ObjectType.Group) { fieldGen = generationDict.GetOrAdd(loqui.GetGroupTarget()); } else { fieldGen = generationDict.GetOrAdd(((object)loqui?.TargetObjectGeneration) ?? loqui); } } else if (field is ContainerType cont) { if (!(cont.SubTypeGeneration is LoquiType contLoqui)) { continue; } if (contLoqui.RefType == LoquiType.LoquiRefType.Generic) { fieldGen = generationDict.GetOrAdd("default:"); } else { fieldGen = generationDict.GetOrAdd(((object)contLoqui?.TargetObjectGeneration) ?? contLoqui); } } else if (field is DictType dict) { if (dict.Mode != DictMode.KeyedValue) { continue; } if (!(dict.ValueTypeGen is LoquiType dictLoqui)) { continue; } if (dictLoqui.RefType == LoquiType.LoquiRefType.Generic) { fieldGen = generationDict.GetOrAdd("default:"); } else { fieldGen = generationDict.GetOrAdd(((object)dictLoqui?.TargetObjectGeneration) ?? dictLoqui); } } else { continue; } await ApplyIterationLines(field, fieldGen, accessor, getter); } bool doAdditionlDeepLogic = obj.Name != "ListGroup"; if (doAdditionlDeepLogic) { var deepRecordMapping = await MajorRecordModule.FindDeepRecords(obj); foreach (var deepRec in deepRecordMapping) { FileGeneration deepFg = generationDict.GetOrAdd(deepRec.Key); foreach (var field in deepRec.Value) { await ApplyIterationLines(field, deepFg, accessor, getter, targetObj : deepRec.Key); } } HashSet <string> blackList = new HashSet <string>(); foreach (var kv in generationDict) { switch (kv.Key) { case LoquiType loqui: if (loqui.RefType == LoquiType.LoquiRefType.Generic) { // Handled in default case continue; } else { fg.AppendLine($"case \"{loqui.Interface(getter: true)}\":"); fg.AppendLine($"case \"{loqui.Interface(getter: false)}\":"); if (loqui.HasInternalGetInterface) { fg.AppendLine($"case \"{loqui.Interface(getter: true, internalInterface: true)}\":"); } if (loqui.HasInternalSetInterface) { fg.AppendLine($"case \"{loqui.Interface(getter: false, internalInterface: true)}\":"); } if (loqui.RefType == LoquiType.LoquiRefType.Interface) { blackList.Add(loqui.SetterInterface); } } break; case ObjectGeneration targetObj: fg.AppendLine($"case \"{targetObj.ObjectName}\":"); fg.AppendLine($"case \"{targetObj.Interface(getter: true)}\":"); fg.AppendLine($"case \"{targetObj.Interface(getter: false)}\":"); if (targetObj.HasInternalGetInterface) { fg.AppendLine($"case \"{targetObj.Interface(getter: true, internalInterface: true)}\":"); } if (targetObj.HasInternalSetInterface) { fg.AppendLine($"case \"{targetObj.Interface(getter: false, internalInterface: true)}\":"); } break; case string str: if (str != "default:") { throw new NotImplementedException(); } continue; default: throw new NotImplementedException(); } using (new DepthWrapper(fg)) { fg.AppendLines(kv.Value); fg.AppendLine("yield break;"); } } // Generate for major record marker interfaces if (LinkInterfaceModule.ObjectMappings.TryGetValue(obj.ProtoGen.Protocol, out var interfs)) { foreach (var interf in interfs) { if (blackList.Contains(interf.Key)) { continue; } FileGeneration subFg = new FileGeneration(); HashSet <ObjectGeneration> passedObjects = new HashSet <ObjectGeneration>(); HashSet <TypeGeneration> deepObjects = new HashSet <TypeGeneration>(); foreach (var subObj in interf.Value) { var grup = obj.Fields .WhereCastable <TypeGeneration, GroupType>() .Where(g => g.GetGroupTarget() == subObj) .FirstOrDefault(); if (grup != null) { subFg.AppendLine($"foreach (var item in EnumerateMajorRecords({accessor}, typeof({grup.GetGroupTarget().Interface(getter: true)}), throwIfUnknown: throwIfUnknown))"); using (new BraceWrapper(subFg)) { subFg.AppendLine("yield return item;"); } passedObjects.Add(grup.GetGroupTarget()); } else if (deepRecordMapping.TryGetValue(subObj, out var deepRec)) { foreach (var field in deepRec) { deepObjects.Add(field); } } } foreach (var deepObj in deepObjects) { await ApplyIterationLines(deepObj, subFg, accessor, getter, blackList : passedObjects); } if (!subFg.Empty) { fg.AppendLine($"case \"{interf.Key}\":"); using (new BraceWrapper(fg)) { fg.AppendLine($"if (!{obj.RegistrationName}.SetterType.IsAssignableFrom(obj.GetType())) yield break;"); fg.AppendLines(subFg); fg.AppendLine("yield break;"); } fg.AppendLine($"case \"{interf.Key}Getter\":"); using (new BraceWrapper(fg)) { fg.AppendLines(subFg); fg.AppendLine("yield break;"); } } } } } fg.AppendLine("default:"); using (new DepthWrapper(fg)) { if (generationDict.TryGetValue("default:", out var gen)) { fg.AppendLines(gen); fg.AppendLine("yield break;"); } else { fg.AppendLine("if (throwIfUnknown)"); using (new BraceWrapper(fg)) { fg.AppendLine("throw new ArgumentException($\"Unknown major record type: {type}\");"); } fg.AppendLine($"else"); using (new BraceWrapper(fg)) { fg.AppendLine("yield break;"); } } } } } } fg.AppendLine(); // Generate base overrides foreach (var baseClass in obj.BaseClassTrail()) { if (await MajorRecordModule.HasMajorRecords(baseClass, includeBaseClass: true, includeSelf: true) != Case.No) { using (var args = new FunctionWrapper(fg, $"public override IEnumerable<TMajor> EnumerateMajorRecords<TMajor>")) { args.Add($"{baseClass.Interface(getter: getter)} obj"); args.Wheres.Add($"where TMajor : {nameof(IMajorRecordCommon)}{(getter ? "Getter" : null)}"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, "EnumerateMajorRecords<TMajor>")) { args.Add($"({obj.Interface(getter: getter)})obj"); } } fg.AppendLine(); } } }
public override async Task PreLoad(ObjectGeneration obj) { if (obj.GetObjectType() != ObjectType.Mod) { return; } var elems = obj.Node.Elements(XName.Get(GameReleaseOptions, LoquiGenerator.Namespace)); if (!elems.Any()) { return; } var objData = obj.GetObjectData(); objData.GameReleaseOptions = elems.Select(el => Enum.Parse <GameRelease>(el.Value)).ToHashSet(); obj.Interfaces.Add(LoquiInterfaceDefinitionType.IGetter, $"IMajorRecordContextEnumerable<{obj.Interface(getter: false, internalInterface: true)}, {obj.Interface(getter: true, internalInterface: true)}>"); }
protected override void FillPublicElement(ObjectGeneration obj, FileGeneration fg) { using (var args = new FunctionWrapper(fg, $"public static void FillPublicElement{ModuleNickname}")) { args.Add($"{obj.Interface(getter: false, internalInterface: true)} item"); args.Add($"XElement {XmlTranslationModule.XElementLine.GetParameterName(obj)}"); args.Add("string name"); args.Add($"ErrorMaskBuilder? errorMask"); args.Add($"{nameof(TranslationCrystal)}? translationMask"); } using (new BraceWrapper(fg)) { fg.AppendLine("switch (name)"); using (new BraceWrapper(fg)) { bool isInRange = false; foreach (var field in obj.IterateFields(expandSets: SetMarkerType.ExpandSets.FalseAndInclude, nonIntegrated: true)) { if (field is DataType set) { foreach (var subField in set.IterateFieldsWithMeta()) { if (subField.Field.Derivative) { continue; } if (subField.Field.ReadOnly) { continue; } if (!subField.Field.IntegrateField) { continue; } if (!this.TryGetTypeGeneration(subField.Field.GetType(), out var generator)) { throw new ArgumentException("Unsupported type generator: " + subField.Field); } fg.AppendLine($"case \"{subField.Field.Name}\":"); using (new DepthWrapper(fg)) { if (generator.ShouldGenerateCopyIn(subField.Field)) { generator.GenerateCopyIn( fg: fg, objGen: obj, typeGen: subField.Field, nodeAccessor: XmlTranslationModule.XElementLine.GetParameterName(obj).Result, itemAccessor: Accessor.FromType(subField.Field, "item"), translationMaskAccessor: "translationMask", errorMaskAccessor: $"errorMask"); } HandleDataTypeParsing(obj, fg, set, subField, ref isInRange); fg.AppendLine("break;"); } } } else if (field.IntegrateField) { if (field.Derivative) { continue; } if (field.ReadOnly) { continue; } if (!this.TryGetTypeGeneration(field.GetType(), out var generator)) { throw new ArgumentException("Unsupported type generator: " + field); } fg.AppendLine($"case \"{field.Name}\":"); using (new DepthWrapper(fg)) { if (generator.ShouldGenerateCopyIn(field)) { generator.GenerateCopyIn( fg: fg, objGen: obj, typeGen: field, nodeAccessor: XmlTranslationModule.XElementLine.GetParameterName(obj).Result, itemAccessor: Accessor.FromType(field, "item"), translationMaskAccessor: "translationMask", errorMaskAccessor: $"errorMask"); } fg.AppendLine("break;"); } } } fg.AppendLine("default:"); using (new DepthWrapper(fg)) { if (obj.HasLoquiBaseObject) { using (var args = new ArgsWrapper(fg, $"{this.TranslationCreateClass(obj.BaseClass)}.FillPublicElement{ModuleNickname}")) { args.Add("item: item"); args.Add($"{XmlTranslationModule.XElementLine.GetParameterName(obj)}: {XmlTranslationModule.XElementLine.GetParameterName(obj)}"); args.Add("name: name"); args.Add("errorMask: errorMask"); if (this.TranslationMaskParameter) { args.Add($"translationMask: translationMask"); } } } fg.AppendLine("break;"); } } } fg.AppendLine(); }
public override async Task GenerateInCommon(ObjectGeneration obj, FileGeneration fg, MaskTypeSet maskTypes) { if (maskTypes.Applicable(LoquiInterfaceType.IGetter, CommonGenerics.Class)) { fg.AppendLine($"public IEnumerable<{nameof(FormLinkInformation)}> GetContainedFormLinks({obj.Interface(getter: true)} obj)"); using (new BraceWrapper(fg)) { foreach (var baseClass in obj.BaseClassTrail()) { if (await HasLinks(baseClass, includeBaseClass: true) != LinkCase.No) { fg.AppendLine("foreach (var item in base.GetContainedFormLinks(obj))"); using (new BraceWrapper(fg)) { fg.AppendLine("yield return item;"); } break; } } var startCount = fg.Count; foreach (var field in obj.IterateFields(nonIntegrated: true)) { if (field is FormLinkType formLink) { if (field.Nullable) { fg.AppendLine($"if (obj.{field.Name}.{formLink.FormIDTypeString}.HasValue)"); using (new BraceWrapper(fg)) { fg.AppendLine($"yield return {nameof(FormLinkInformation)}.{nameof(FormLinkInformation.Factory)}(obj.{field.Name});"); } } else if (formLink.FormIDType == FormLinkType.FormIDTypeEnum.Normal) { fg.AppendLine($"yield return {nameof(FormLinkInformation)}.{nameof(FormLinkInformation.Factory)}(obj.{field.Name});"); } } else if (field is LoquiType loqui) { LinkCase subLinkCase; if (loqui.TargetObjectGeneration != null) { subLinkCase = await HasLinks(loqui, includeBaseClass : true); } else { subLinkCase = LinkCase.Maybe; } if (subLinkCase == LinkCase.No) { continue; } var doBrace = true; var access = $"obj.{field.Name}"; if (subLinkCase == LinkCase.Maybe) { fg.AppendLine($"if (obj.{field.Name} is {nameof(IFormLinkContainerGetter)} {field.Name}linkCont)"); access = $"{field.Name}linkCont"; } else if (loqui.Nullable) { fg.AppendLine($"if (obj.{field.Name}.TryGet(out var {field.Name}Items))"); access = $"{field.Name}Items"; } else { doBrace = false; } using (new BraceWrapper(fg, doIt: doBrace)) { fg.AppendLine($"foreach (var item in {access}.{nameof(IFormLinkContainerGetter.ContainedFormLinks)})"); using (new BraceWrapper(fg)) { fg.AppendLine($"yield return item;"); } } } else if (field is WrapperType cont) { var access = $"obj.{field.Name}"; if (field.Nullable) { access = $"{field.Name}Item"; } FileGeneration subFg = new FileGeneration(); if (cont.SubTypeGeneration is LoquiType contLoqui && await HasLinks(contLoqui, includeBaseClass: true) != LinkCase.No) { string filterNulls = cont is GenderedType && ((GenderedType)cont).ItemNullable ? ".NotNull()" : null; var linktype = await HasLinks(contLoqui, includeBaseClass : true); if (linktype != LinkCase.No) { switch (linktype) { case LinkCase.Yes: subFg.AppendLine($"foreach (var item in {access}{filterNulls}.SelectMany(f => f.{nameof(IFormLinkContainerGetter.ContainedFormLinks)}))"); break; case LinkCase.Maybe: subFg.AppendLine($"foreach (var item in {access}{filterNulls}.WhereCastable<{contLoqui.TypeName(getter: true)}, {nameof(IFormLinkContainerGetter)}>()"); using (new DepthWrapper(subFg)) { subFg.AppendLine($".SelectMany((f) => f.{nameof(IFormLinkContainerGetter.ContainedFormLinks)}))"); } break; default: throw new NotImplementedException(); } } } else if (cont.SubTypeGeneration is FormLinkType formIDType && formIDType.FormIDType == FormLinkType.FormIDTypeEnum.Normal) { string filterNulls = cont is GenderedType && ((GenderedType)cont).ItemNullable ? ".NotNull()" : null; subFg.AppendLine($"foreach (var item in {access}{filterNulls})"); } else { continue; } if (field.Nullable) { fg.AppendLine($"if (obj.{field.Name}.TryGet(out var {field.Name}Item))"); } using (new BraceWrapper(fg, doIt: field.Nullable)) { fg.AppendLines(subFg); using (new BraceWrapper(fg)) { fg.AppendLine($"yield return {nameof(FormLinkInformation)}.{nameof(FormLinkInformation.Factory)}(item);"); } } }
public override async Task GenerateInCommon(ObjectGeneration obj, FileGeneration fg, MaskTypeSet maskTypes) { if (!maskTypes.Applicable(LoquiInterfaceType.IGetter, CommonGenerics.Class)) { return; } await base.GenerateInCommon(obj, fg, maskTypes); if (!await obj.IsMajorRecord()) { return; } using (new RegionWrapper(fg, "Duplicate")) { using (var args = new FunctionWrapper(fg, $"public{obj.Virtual()}{obj.Name} Duplicate{obj.GetGenericTypes(MaskType.Normal, MaskType.NormalGetter)}")) { args.Wheres.AddRange(obj.GenericTypeMaskWheres(LoquiInterfaceType.IGetter, MaskType.Normal, MaskType.NormalGetter)); args.Add($"{obj.Interface(getter: true)} item"); args.Add($"{nameof(FormKey)} formKey"); args.Add($"TranslationCrystal? copyMask"); } using (new BraceWrapper(fg)) { if (obj.Abstract) { fg.AppendLine("throw new NotImplementedException();"); } else { fg.AppendLine($"var newRec = new {obj.Name}(formKey{(obj.GetObjectData().HasMultipleReleases ? $", item.FormVersion" : null)});"); fg.AppendLine($"newRec.DeepCopyIn(item, default({nameof(ErrorMaskBuilder)}?), copyMask);"); fg.AppendLine("return newRec;"); } } fg.AppendLine(); foreach (var baseClass in obj.BaseClassTrail()) { using (var args = new FunctionWrapper(fg, $"public override {baseClass.Name} Duplicate{baseClass.GetGenericTypes(MaskType.Normal, MaskType.NormalGetter)}")) { args.Wheres.AddRange(baseClass.GenericTypeMaskWheres(LoquiInterfaceType.IGetter, MaskType.Normal, MaskType.NormalGetter)); args.Add($"{baseClass.Interface(getter: true)} item"); args.Add($"{nameof(FormKey)} formKey"); args.Add($"TranslationCrystal? copyMask"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"return this.Duplicate")) { args.Add($"item: ({obj.Interface(getter: true)})item"); args.AddPassArg("formKey"); args.AddPassArg("copyMask"); } } fg.AppendLine(); } } }
public override async Task GenerateInCommonMixin(ObjectGeneration obj, FileGeneration fg) { if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"{nameof(FormKey)} key"); } using (new BraceWrapper(fg)) { fg.AppendLine($"var keys = new HashSet<{nameof(FormKey)}>();"); fg.AppendLine("keys.Add(key);"); using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.AddPassArg("keys"); } } fg.AppendLine(); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"IEnumerable<{nameof(FormKey)}> keys"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.Add("keys: keys.ToHashSet()"); } } fg.AppendLine(); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"HashSet<{nameof(FormKey)}> keys"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.AddPassArg("keys"); } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"{nameof(FormKey)} key"); args.Add($"{nameof(Type)} type"); args.Add($"bool throwIfUnknown = true"); } using (new BraceWrapper(fg)) { fg.AppendLine($"var keys = new HashSet<{nameof(FormKey)}>();"); fg.AppendLine("keys.Add(key);"); using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.AddPassArg("keys"); args.AddPassArg("type"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"IEnumerable<{nameof(FormKey)}> keys"); args.Add($"{nameof(Type)} type"); args.Add($"bool throwIfUnknown = true"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.Add("keys: keys.ToHashSet()"); args.AddPassArg("type"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal)}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"HashSet<{nameof(FormKey)}> keys"); args.Add($"{nameof(Type)} type"); args.Add($"bool throwIfUnknown = true"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.AddPassArg("keys"); args.AddPassArg("type"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal, "TMajor")}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"TMajor record"); args.Add($"bool throwIfUnknown = true"); args.Wheres.Add($"where TMajor : {nameof(IMajorRecordCommonGetter)}"); } using (new BraceWrapper(fg)) { fg.AppendLine($"var keys = new HashSet<{nameof(FormKey)}>();"); fg.AppendLine("keys.Add(record.FormKey);"); using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.AddPassArg("keys"); args.Add("type: typeof(TMajor)"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal, "TMajor")}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"IEnumerable<TMajor> records"); args.Add($"bool throwIfUnknown = true"); args.Wheres.Add($"where TMajor : {nameof(IMajorRecordCommonGetter)}"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.Add("keys: records.Select(m => m.FormKey).ToHashSet()"); args.Add("type: typeof(TMajor)"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal, "TMajor")}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"{nameof(FormKey)} key"); args.Add($"bool throwIfUnknown = true"); args.Wheres.Add($"where TMajor : {nameof(IMajorRecordCommonGetter)}"); } using (new BraceWrapper(fg)) { fg.AppendLine($"var keys = new HashSet<{nameof(FormKey)}>();"); fg.AppendLine("keys.Add(key);"); using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.AddPassArg("keys"); args.Add("type: typeof(TMajor)"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal, "TMajor")}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"IEnumerable<{nameof(FormKey)}> keys"); args.Add($"bool throwIfUnknown = true"); args.Wheres.Add($"where TMajor : {nameof(IMajorRecordCommonGetter)}"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.Add("keys: keys.ToHashSet()"); args.Add("type: typeof(TMajor)"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); if (await MajorRecordModule.HasMajorRecordsInTree(obj, includeBaseClass: false) == Case.No) { return; } fg.AppendLine("[DebuggerStepThrough]"); using (var args = new FunctionWrapper(fg, $"public static void Remove{obj.GetGenericTypes(MaskType.Normal, "TMajor")}")) { args.Wheres.AddRange(obj.GenerateWhereClauses(LoquiInterfaceType.ISetter, obj.Generics)); args.Add($"this {obj.Interface(getter: false, internalInterface: true)} obj"); args.Add($"HashSet<{nameof(FormKey)}> keys"); args.Add($"bool throwIfUnknown = true"); args.Wheres.Add($"where TMajor : {nameof(IMajorRecordCommonGetter)}"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"{obj.CommonClassInstance("obj", LoquiInterfaceType.ISetter, CommonGenerics.Class)}.Remove")) { args.AddPassArg("obj"); args.AddPassArg("keys"); args.Add("type: typeof(TMajor)"); args.AddPassArg("throwIfUnknown"); } } fg.AppendLine(); }
public override async Task GenerateInVoid(ObjectGeneration obj, FileGeneration fg) { if (obj.GetObjectType() != ObjectType.Mod) { return; } using (new NamespaceWrapper(fg, obj.Namespace)) { fg.AppendLine("public class GroupMask"); using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration == null) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"public bool {loqui.Name};"); } fg.AppendLine("public GroupMask()"); using (new BraceWrapper(fg)) { } fg.AppendLine("public GroupMask(bool defaultValue)"); using (new BraceWrapper(fg)) { foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration == null) { continue; } if (loqui.TargetObjectGeneration.GetObjectType() != ObjectType.Group) { continue; } fg.AppendLine($"{loqui.Name} = defaultValue;"); } } } fg.AppendLine(); fg.AppendLine($"public interface I{obj.Name}DisposableGetter : {obj.Interface(getter: true, internalInterface: true)}, IModDisposeGetter"); using (new BraceWrapper(fg)) { } } }