示例#1
0
        public override Task PostFieldLoad(ObjectGeneration obj, TypeGeneration field, XElement node)
        {
            var data = field.CustomData.TryCreateValue(Constants.DataKey, () => new MutagenFieldData(field)) as MutagenFieldData;

            if (node.TryGetAttribute("recordType", out string recordAttr))
            {
                data.RecordType = new RecordType(recordAttr);
            }
            else if (node.TryGetAttribute("recordTypeHex", out string recordAttrInt))
            {
                data.RecordType = new RecordType(Convert.ToInt32(recordAttrInt, 16));
            }
            if (node.TryGetAttribute("overflowRecordType", out var overflow))
            {
                data.OverflowRecordType = new RecordType(overflow.Value);
            }
            var markerAttr = node.GetAttribute("markerType");

            if (markerAttr != null)
            {
                data.MarkerType = new RecordType(markerAttr);
            }
            if (obj.IsTopLevelGroup() && (field.Name?.Equals("Items") ?? false))
            {
                DictType  dict  = field as DictType;
                LoquiType loqui = dict.ValueTypeGen as LoquiType;
                data.TriggeringRecordAccessors.Add($"Group<T>.T_RecordType");
            }
            return(base.PostFieldLoad(obj, field, node));
        }
        public override void GenerateCopyInRet(
            FileGeneration fg,
            ObjectGeneration objGen,
            TypeGeneration targetGen,
            TypeGeneration typeGen,
            Accessor readerAccessor,
            AsyncMode asyncMode,
            Accessor retAccessor,
            Accessor outItemAccessor,
            Accessor errorMaskAccessor,
            Accessor translationAccessor,
            Accessor converterAccessor,
            bool inline)
        {
            LoquiType loqui = typeGen as LoquiType;

            if (inline)
            {
                if (loqui.GenericDef != null)
                {
                    fg.AppendLine($"{retAccessor}{Loqui.Generation.Utility.Await(asyncMode)}LoquiBinary{(asyncMode == AsyncMode.Off ? null : "Async")}Translation<{loqui.ObjectTypeName}{loqui.GenericTypes(getter: false)}>.Instance.Parse");
                }
                else
                {
                    fg.AppendLine($"{retAccessor}{loqui.ObjectTypeName}{loqui.GenericTypes(getter: false)}.TryCreateFromBinary");
                }
            }
            else
            {
                fg.AppendLine($"var ret = {loqui.ObjectTypeName}{loqui.GenericTypes(getter: false)}.TryCreateFromBinary({readerAccessor}, out var tmp{outItemAccessor}, {converterAccessor});");
                fg.AppendLine($"{outItemAccessor} = tmp{outItemAccessor};");
                fg.AppendLine("return ret;");
            }
        }
示例#3
0
    public void AddMaskException(StructuredStringBuilder sb, string errorMaskAccessor, string exception, bool key)
    {
        LoquiType valueLoquiType = ValueTypeGen as LoquiType;
        var       valStr         = valueLoquiType == null ? "Exception" : $"Tuple<Exception, {valueLoquiType.TargetObjectGeneration.GetMaskString("Exception")}>";

        sb.AppendLine($"{errorMaskAccessor}?.{Name}.Value.Add({(key ? "null" : exception)});");
    }
 public static async Task <Case> HasMajorRecords(LoquiType loqui, bool includeBaseClass, GenericSpecification specifications = null, bool includeSelf = true)
 {
     if (loqui.TargetObjectGeneration != null)
     {
         if (includeSelf && await loqui.TargetObjectGeneration.IsMajorRecord())
         {
             return(Case.Yes);
         }
         return(await MajorRecordModule.HasMajorRecordsInTree(loqui.TargetObjectGeneration, includeBaseClass, loqui.GenericSpecification));
     }
     else if (specifications != null)
     {
         foreach (var target in specifications.Specifications.Values)
         {
             if (!ObjectNamedKey.TryFactory(target, out var key))
             {
                 continue;
             }
             var specObj = loqui.ObjectGen.ProtoGen.Gen.ObjectGenerationsByObjectNameKey[key];
             if (await specObj.IsMajorRecord())
             {
                 return(Case.Yes);
             }
             return(await MajorRecordModule.HasMajorRecordsInTree(specObj, includeBaseClass));
         }
     }
     else if (loqui.RefType == LoquiType.LoquiRefType.Interface)
     {
         // ToDo
         // Quick hack.  Real solution should use reflection to investigate the interface
         return(includeSelf ? Case.Yes : Case.No);
     }
     return(Case.Maybe);
 }
        public override Task GenerateInRegistration(ObjectGeneration obj, FileGeneration fg)
        {
            var objData = obj.GetObjectData();

            GenerateConverterMember(fg, obj.BaseClass, objData.BaseRecordTypeConverter, "Base");
            foreach (var field in obj.IterateFields(expandSets: SetMarkerType.ExpandSets.FalseAndInclude, nonIntegrated: true))
            {
                LoquiType loquiType = field as LoquiType;
                if (loquiType == null)
                {
                    switch (field)
                    {
                    case WrapperType wrapper:
                        loquiType = wrapper.SubTypeGeneration as LoquiType;
                        if (loquiType != null)
                        {
                            break;
                        }
                        continue;

                    default:
                        continue;
                    }
                }
                var fieldData = loquiType.GetFieldData();
                GenerateConverterMember(fg, loquiType.TargetObjectGeneration, fieldData.RecordTypeConverter, field.Name);
            }
            return(base.GenerateInRegistration(obj, fg));
        }
示例#6
0
    public void AddMaskException(StructuredStringBuilder sb, string errorMaskMemberAccessor, string exception, bool key)
    {
        LoquiType keyLoquiType   = KeyTypeGen as LoquiType;
        LoquiType valueLoquiType = ValueTypeGen as LoquiType;
        var       item2          = $"KeyValuePair<{(keyLoquiType == null ? "Exception" : keyLoquiType.TargetObjectGeneration.GetMaskString("Exception"))}, {(valueLoquiType == null ? "Exception" : valueLoquiType.TargetObjectGeneration.GetMaskString("Exception"))}>";

        sb.AppendLine($"{errorMaskMemberAccessor}?.{Name}.Value.Add(new {item2}({(key ? exception : "null")}, {(key ? "null" : exception)}));");
    }
        public override string GenerateForTypicalWrapper(
            ObjectGeneration objGen,
            TypeGeneration typeGen,
            Accessor dataAccessor,
            Accessor packageAccessor)
        {
            LoquiType loqui = typeGen as LoquiType;

            return($"{this.Module.BinaryOverlayClass(loqui.TargetObjectGeneration)}.{loqui.TargetObjectGeneration.Name}Factory({dataAccessor}, {packageAccessor})");
        }
示例#8
0
 public override void GenerateForCopy(FileGeneration fg, Accessor accessor, Accessor rhs, Accessor copyMaskAccessor, bool protectedMembers, bool deepCopy)
 {
     if (!deepCopy)
     {
         throw new NotImplementedException();
     }
     if (this.Nullable)
     {
         fg.AppendLine($"if (!{rhs}.TryGet(out var rhs{this.Name}item))");
         using (new BraceWrapper(fg))
         {
             fg.AppendLine($"{accessor} = null;");
         }
         fg.AppendLine("else");
         rhs = $"rhs{this.Name}item";
     }
     using (new BraceWrapper(fg, doIt: this.Nullable))
     {
         using (var args = new ArgsWrapper(fg,
                                           $"{accessor} = new GenderedItem<{this.SubTypeGeneration.TypeName(getter: false, needsCovariance: true)}{this.SubTypeGeneration.NullChar}>"))
         {
             if (this.isLoquiSingle)
             {
                 LoquiType loqui = this.SubTypeGeneration as LoquiType;
                 args.Add(subFg =>
                 {
                     loqui.GenerateTypicalMakeCopy(
                         subFg,
                         retAccessor: $"male: ",
                         rhsAccessor: $"{rhs}.Male{this.SubTypeGeneration.NullChar}",
                         copyMaskAccessor: $"{copyMaskAccessor}.Male",
                         deepCopy: deepCopy,
                         doTranslationMask: false);
                 });
                 args.Add(subFg =>
                 {
                     loqui.GenerateTypicalMakeCopy(
                         subFg,
                         retAccessor: $"female: ",
                         rhsAccessor: $"{rhs}.Female{this.SubTypeGeneration.NullChar}",
                         copyMaskAccessor: $"{copyMaskAccessor}.Female",
                         deepCopy: deepCopy,
                         doTranslationMask: false);
                 });
             }
             else
             {
                 args.Add($"male: {this.SubTypeGeneration.GetDuplicate($"{rhs}.Male")}");
                 args.Add($"female: {this.SubTypeGeneration.GetDuplicate($"{rhs}.Female")}");
             }
         }
     }
 }
 public bool NeedsHeaderProcessing(LoquiType loquiGen)
 {
     if (!loquiGen.Singleton &&
         loquiGen.TargetObjectGeneration != null &&
         loquiGen.GetFieldData().HasTrigger &&
         !loquiGen.TargetObjectGeneration.Abstract &&
         loquiGen.TargetObjectGeneration.GetObjectData().TriggeringSource == null)
     {
         return(true);
     }
     return(false);
 }
示例#10
0
    public override void GenerateForErrorMaskCombine(StructuredStringBuilder sb, TypeGeneration field, string accessor, string retAccessor, string rhsAccessor)
    {
        LoquiType loqui = field as LoquiType;

        if (!IsUnknownGeneric(loqui))
        {
            sb.AppendLine($"{retAccessor} = {accessor}.Combine({rhsAccessor}, (l, r) => l.Combine(r));");
        }
        else
        {
            sb.AppendLine($"{retAccessor} = new MaskItem<Exception?, {loqui.Mask(MaskType.Error)}?>(ExceptionExt.Combine({accessor}.Overall, {rhsAccessor}.Overall), Loqui.Internal.LoquiHelper.Combine({accessor}.Specific, {rhsAccessor}.Specific));");
        }
    }
示例#11
0
    public override void GenerateForTranslationMask(StructuredStringBuilder sb, TypeGeneration field)
    {
        LoquiType loqui = field as LoquiType;

        if (loqui.RefType == LoquiRefType.Direct)
        {
            sb.AppendLine($"public {loqui.Mask(MaskType.Translation)}? {field.Name};");
        }
        else
        {
            sb.AppendLine($"public bool {field.Name};");
        }
    }
示例#12
0
    public override void GenerateForTranslate(StructuredStringBuilder sb, TypeGeneration field, string retAccessor, string rhsAccessor, bool indexed)
    {
        LoquiType loqui = field as LoquiType;

        if (IsUnknownGeneric(loqui))
        {
            sb.AppendLine($"{retAccessor};");
            sb.AppendLine($"throw new {nameof(NotImplementedException)}();");
        }
        else
        {
            sb.AppendLine($"{retAccessor} = {rhsAccessor} == null ? null : new MaskItem{(indexed ? "Indexed" : null)}<R, {loqui.GenerateMaskString("R")}?>({(indexed ? $"{rhsAccessor}.Index, " : null)}eval({rhsAccessor}.Overall), {rhsAccessor}.Specific?.Translate(eval));");
        }
    }
示例#13
0
 public static async Task <bool> IsMajorRecord(this LoquiType loqui)
 {
     if (loqui.TargetObjectGeneration != null)
     {
         return(await IsMajorRecord(loqui.TargetObjectGeneration));
     }
     else if (loqui.RefType == LoquiType.LoquiRefType.Interface)
     {
         // ToDo
         // Quick hack.  Real solution should use reflection to investigate the interface
         return(true);
     }
     return(false);
 }
示例#14
0
 public static async IAsyncEnumerable <ObjectGeneration> IterateMajorRecords(LoquiType loqui, bool includeBaseClass, GenericSpecification specifications = null)
 {
     if (specifications?.Specifications.Count > 0)
     {
         foreach (var target in specifications.Specifications.Values)
         {
             if (!ObjectNamedKey.TryFactory(target, out var key))
             {
                 continue;
             }
             var specObj = loqui.ObjectGen.ProtoGen.Gen.ObjectGenerationsByObjectNameKey[key];
             if (await specObj.IsMajorRecord())
             {
                 yield return(specObj);
             }
             await foreach (var item in IterateMajorRecords(specObj, includeBaseClass, includeSelf: true, loqui.GenericSpecification))
             {
                 yield return(item);
             }
         }
     }
     else if (loqui.TargetObjectGeneration != null)
     {
         if (await loqui.TargetObjectGeneration.IsMajorRecord())
         {
             yield return(loqui.TargetObjectGeneration);
         }
         await foreach (var item in IterateMajorRecords(loqui.TargetObjectGeneration, includeBaseClass, includeSelf: true, loqui.GenericSpecification))
         {
             yield return(item);
         }
     }
     else if (loqui.RefType == LoquiType.LoquiRefType.Interface)
     {
         // Must be a link interface
         if (!LinkInterfaceModule.ObjectMappings[loqui.ObjectGen.ProtoGen.Protocol].TryGetValue(loqui.SetterInterface, out var mappings))
         {
             throw new ArgumentException();
         }
         foreach (var obj in mappings)
         {
             yield return(obj);
         }
     }
     else
     {
         throw new ArgumentException();
     }
 }
    public override XElement GenerateForXSD(
        ObjectGeneration objGen,
        XElement rootElement,
        XElement choiceElement,
        TypeGeneration typeGen,
        string nameOverride = null)
    {
        LoquiType loqui           = typeGen as LoquiType;
        var       targetObject    = loqui.TargetObjectGeneration;
        var       targetNamespace = XmlMod.ObjectNamespace(targetObject);
        var       diffNamespace   = !targetNamespace.Equals(XmlMod.ObjectNamespace(objGen));

        if (diffNamespace)
        {
            rootElement.Add(
                new XAttribute(XNamespace.Xmlns + $"{targetObject.Name.ToLower()}", XmlMod.ObjectNamespace(targetObject)));
        }
        FilePath xsdPath      = XmlMod.ObjectXSDLocation(targetObject);
        var      relativePath = xsdPath.GetRelativePathTo(objGen.TargetDir);
        var      importElem   = new XElement(
            XmlTranslationModule.XSDNamespace + "include",
            new XAttribute("schemaLocation", relativePath));

        if (diffNamespace &&
            !rootElement.Elements().Any((e) => e.ContentEqual(importElem)))
        {
            importElem.Add(new XAttribute("namespace", XmlMod.ObjectNamespace(targetObject)));
        }
        if (!rootElement.Elements().Any((e) => e.ContentEqual(importElem)))
        {
            rootElement.AddFirst(importElem);
        }
        var elem = new XElement(
            XmlTranslationModule.XSDNamespace + "element",
            new XAttribute("name", nameOverride ?? loqui.Name));

        if (diffNamespace)
        {
            elem.Add(
                new XAttribute("type", $"{targetObject.Name.ToLower()}:{loqui.TargetObjectGeneration.Name}Type"));
        }
        else
        {
            elem.Add(
                new XAttribute("type", $"{loqui.TargetObjectGeneration.Name}Type"));
        }
        choiceElement.Add(elem);
        return(elem);
    }
        private async Task LoquiTypeHandler(
            FileGeneration fg,
            Accessor loquiAccessor,
            LoquiType loquiType,
            string generic,
            bool checkType,
            ObjectGeneration targetObj = null)
        {
            // ToDo
            // Quick hack.  Real solution should use reflection to investigate the interface
            if (loquiType.RefType == LoquiType.LoquiRefType.Interface)
            {
                if (checkType)
                {
                    fg.AppendLine($"if (type.IsAssignableFrom({loquiAccessor}.GetType()))");
                }
                using (new BraceWrapper(fg, doIt: checkType))
                {
                    fg.AppendLine($"yield return {loquiAccessor};");
                }
                return;
            }

            if (loquiType.TargetObjectGeneration != null &&
                await loquiType.TargetObjectGeneration.IsMajorRecord() &&
                (targetObj == null || targetObj == loquiType.TargetObjectGeneration))
            {
                if (checkType)
                {
                    fg.AppendLine($"if (type.IsAssignableFrom({loquiAccessor}.GetType()))");
                }
                using (new BraceWrapper(fg, doIt: checkType))
                {
                    fg.AppendLine($"yield return {loquiAccessor};");
                }
            }
            if (await MajorRecordModule.HasMajorRecords(loquiType, includeBaseClass: true) == Case.No)
            {
                return;
            }
            fg.AppendLine($"foreach (var item in {loquiAccessor}.EnumerateMajorRecords({(generic == null ? null : "type, throwIfUnknown: false")}))");
            using (new BraceWrapper(fg))
            {
                fg.AppendLine($"yield return item;");
            }
        }
示例#17
0
    public static string GetSubMaskString(IDictType dictType, string typeStr, bool getter)
    {
        LoquiType keyLoquiType   = dictType.KeyTypeGen as LoquiType;
        LoquiType valueLoquiType = dictType.ValueTypeGen as LoquiType;

        switch (dictType.Mode)
        {
        case DictMode.KeyValue:
            if (valueLoquiType != null)
            {
                return($"{(valueLoquiType == null ? $"({dictType.KeyTypeGen.TypeName(getter)} Key, {typeStr} Value)" : $"MaskItemIndexed<{dictType.KeyTypeGen.TypeName(getter)}, {typeStr}, {valueLoquiType.GetMaskString(typeStr)}?>")}");
            }
            else
            {
                string keyStr   = $"{(keyLoquiType == null ? dictType.KeyTypeGen.TypeName(getter: true) : $"MaskItem<{typeStr}, {keyLoquiType.GetMaskString(typeStr)}?>")}";
                string valueStr = $"{(valueLoquiType == null ? typeStr : $"MaskItem<{typeStr}, {valueLoquiType.GetMaskString(typeStr)}?>")}";
                return($"KeyValuePair<{keyStr}, {valueStr}>");
            }
 public static async Task <bool> NeedsRecordTypeConverter(LoquiType loqui)
 {
     foreach (var field in loqui.TargetObjectGeneration.IterateFields(includeBaseClass: true))
     {
         if (field.GetFieldData().HasTrigger)
         {
             return(true);
         }
     }
     foreach (var subObj in await loqui.ObjectGen.InheritingObjects())
     {
         if (subObj.GetObjectData().BaseRecordTypeConverter != null)
         {
             return(true);
         }
     }
     return(false);
 }
示例#19
0
        public static async Task AddAsSubLoquiType(this LoquiType loqui, IEnumerable <ObjectGeneration> objGens)
        {
            var data = loqui.GetFieldData();

            foreach (var subObj in objGens)
            {
                var subRecs = await subObj.TryGetTriggeringRecordTypes();

                if (subRecs.Failed)
                {
                    continue;
                }
                foreach (var subRec in subRecs.Value)
                {
                    data.SubLoquiTypes.TryCreateValue(subRec).Add(subObj);
                }
            }
        }
示例#20
0
    public override void GenerateForAny(StructuredStringBuilder sb, TypeGeneration field, Accessor accessor, bool nullCheck, bool indexed)
    {
        LoquiType loqui = field as LoquiType;

        if (nullCheck)
        {
            sb.AppendLine($"if ({field.Name} != null)");
        }
        using (sb.CurlyBrace(doIt: nullCheck))
        {
            sb.AppendLine($"if (eval({accessor.Access}.Overall)) return true;");
            if (!IsUnknownGeneric(loqui))
            {
                sb.AppendLine($"if ({accessor.Access}.Specific != null && {accessor.Access}.Specific.Any(eval)) return true;");
            }
            else
            {
                sb.AppendLine($"if (({accessor.Access}.Specific?.Any(eval) ?? false)) return true;");
            }
        }
    }
示例#21
0
        public override async Task Load(XElement node, bool requireName = true)
        {
            await base.Load(node, requireName);

            LoquiType  = this.ObjectGen.ProtoGen.Gen.GetTypeGeneration <MutagenLoquiType>();
            _rawFormID = this.ObjectGen.ProtoGen.Gen.GetTypeGeneration <FormIDType>();
            LoquiType.SetObjectGeneration(this.ObjectGen, setDefaults: true);
            LoquiType.RequireInterfaceObject = false;
            await LoquiType.Load(node, requireName : false);

            LoquiType.Name = this.Name;
            LoquiType.GetterInterfaceType = LoquiInterfaceType.IGetter;
            _rawFormID.Name = this.Name;
            _rawFormID.SetObjectGeneration(this.ObjectGen, false);
            this.NotifyingProperty.Subscribe(i => LoquiType.NotifyingProperty.OnNext(i));
            this.NotifyingProperty.Subscribe(i => _rawFormID.NotifyingProperty.OnNext(i));
            this.HasBeenSetProperty.Subscribe(i => LoquiType.HasBeenSetProperty.OnNext(i));
            this.HasBeenSetProperty.Subscribe(i => _rawFormID.HasBeenSetProperty.OnNext(i));
            this.FormIDType    = node.GetAttribute <FormIDTypeEnum>("type", defaultVal: FormIDTypeEnum.Normal);
            this.Singleton     = true;
            this.SetPermission = PermissionLevel.@private;
        }
        public override bool IsAsync(TypeGeneration gen, bool read)
        {
            if (!read)
            {
                return(false);
            }
            LoquiType loqui = gen as LoquiType;

            if (loqui.CustomData.TryGetValue(AsyncOverrideKey, out var asyncOverride))
            {
                return((bool)asyncOverride);
            }
            if (loqui.TargetObjectGeneration != null)
            {
                if (loqui.TargetObjectGeneration.GetObjectData().CustomBinaryEnd == CustomEnd.Async)
                {
                    return(true);
                }
                return(this.Module.HasAsync(loqui.TargetObjectGeneration, self: true));
            }
            return(false);
        }
示例#23
0
        public override void GenerateForEqualsMask(FileGeneration fg, Accessor accessor, Accessor rhsAccessor, string retAccessor)
        {
            LoquiType loqui = this.SubTypeGeneration as LoquiType;

            if (this.Nullable || loqui != null)
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"ret.{this.Name} = {nameof(GenderedItem)}.{nameof(GenderedItem.EqualityMaskHelper)}"))
                {
                    args.Add($"lhs: {accessor}");
                    args.Add($"rhs: {rhsAccessor}");
                    if (loqui == null)
                    {
                        args.Add($"maskGetter: (l, r, i) => EqualityComparer<{this.SubTypeGeneration.TypeName(getter: true, needsCovariance: true)}{this.SubTypeGeneration.NullChar}>.Default.Equals(l, r)");
                    }
                    else
                    {
                        if (this.ItemNullable)
                        {
                            args.Add($"maskGetter: (l, r, i) => EqualsMaskHelper.EqualsHelper(l, r, (loqLhs, loqRhs, incl) => loqLhs.GetEqualsMask(loqRhs, incl), i)");
                        }
                        else
                        {
                            args.Add("maskGetter: (l, r, i) => l.GetEqualsMask(r, i)");
                        }
                    }
                    args.AddPassArg("include");
                }
            }
            else
            {
                using (var args = new ArgsWrapper(fg,
                                                  $"ret.{this.Name} = new GenderedItem<bool>"))
                {
                    args.Add($"male: {this.SubTypeGeneration.GenerateEqualsSnippet($"{accessor}.Male", $"{rhsAccessor}.Male")}");
                    args.Add($"female: {this.SubTypeGeneration.GenerateEqualsSnippet($"{accessor}.Female", $"{rhsAccessor}.Female")}");
                }
            }
        }
示例#24
0
    public void GenerateForEqualsMaskCheck(StructuredStringBuilder sb, string accessor, string rhsAccessor, string retAccessor)
    {
        LoquiType keyLoqui = KeyTypeGen as LoquiType;
        LoquiType valLoqui = ValueTypeGen as LoquiType;

        if (keyLoqui != null &&
            valLoqui != null)
        {
            throw new NotImplementedException();
        }
        else if (keyLoqui != null)
        {
            throw new NotImplementedException();
        }
        else if (valLoqui != null)
        {
            using (var args = sb.Call(
                       $"{retAccessor} = EqualsMaskHelper.DictEqualsHelper"))
            {
                args.Add($"lhs: {accessor}");
                args.Add($"rhs: {rhsAccessor}");
                args.Add($"maskGetter: (k, l, r) => l.GetEqualsMask(r, include)");
                args.AddPassArg("include");
            }
        }
        else
        {
            using (var args = sb.Call(
                       $"{retAccessor} = EqualsMaskHelper.DictEqualsHelper"))
            {
                args.Add($"lhs: {accessor}");
                args.Add($"rhs: {rhsAccessor}");
                args.AddPassArg("include");
            }
        }
    }
示例#25
0
 public static async Task <Case> HasLinks(LoquiType loqui, bool includeBaseClass, GenericSpecification specifications = null)
 {
     if (loqui.TargetObjectGeneration != null)
     {
         return(await HasLinks(loqui.TargetObjectGeneration, includeBaseClass, loqui.GenericSpecification));
     }
     else if (specifications != null)
     {
         foreach (var target in specifications.Specifications.Values)
         {
             if (!ObjectNamedKey.TryFactory(target, out var key))
             {
                 continue;
             }
             var specObj = loqui.ObjectGen.ProtoGen.Gen.ObjectGenerationsByObjectNameKey[key];
             return(await HasLinks(specObj, includeBaseClass));
         }
         return(Case.Maybe);
     }
     else
     {
         return(Case.Maybe);
     }
 }
示例#26
0
    public override void GenerateForCopyMaskCtor(StructuredStringBuilder sb, TypeGeneration field, string basicValueStr, string deepCopyStr)
    {
        LoquiType loqui = field as LoquiType;

        if (loqui.RefType == LoquiRefType.Direct)
        {
            if (loqui.Singleton)
            {
                if (loqui.SetterInterfaceType == LoquiInterfaceType.IGetter)
                {
                    return;
                }
                sb.AppendLine($"this.{field.Name} = new MaskItem<bool, {loqui.Mask(MaskType.Copy)}>({basicValueStr}, default);");
            }
            else
            {
                sb.AppendLine($"this.{field.Name} = new MaskItem<{nameof(CopyOption)}, {loqui.Mask(MaskType.Copy)}>({deepCopyStr}, default);");
            }
        }
        else
        {
            sb.AppendLine($"this.{field.Name} = {deepCopyStr};");
        }
    }
示例#27
0
    public override void GenerateForCopyMask(StructuredStringBuilder sb, TypeGeneration field)
    {
        LoquiType loqui = field as LoquiType;

        if (loqui.RefType == LoquiRefType.Direct)
        {
            if (loqui.Singleton)
            {
                if (loqui.SetterInterfaceType == LoquiInterfaceType.IGetter)
                {
                    return;
                }
                sb.AppendLine($"public MaskItem<bool, {loqui.Mask(MaskType.Copy)}> {field.Name};");
            }
            else
            {
                sb.AppendLine($"public MaskItem<{nameof(CopyOption)}, {loqui.Mask(MaskType.Copy)}> {field.Name};");
            }
        }
        else
        {
            sb.AppendLine($"public {nameof(CopyOption)} {field.Name};");
        }
    }
示例#28
0
        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))
            {
                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});");
                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 == "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}, writer.MetaData.MasterReferences!, {i}{(objData.GameReleaseOptions == null ? null : ", gameConstants")}, outputStreams{(objData.UsesStringFiles ? ", param.StringsWriter" : null)}));");
                    }
                    else
                    {
                        fg.AppendLine($"toDo.Add(() => Write{field.Name}Parallel(item.{field.Name}, writer.MetaData.MasterReferences!, {i}{(objData.GameReleaseOptions == null ? null : ", gameConstants")}, 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");
                    if (objData.GameReleaseOptions != null)
                    {
                        args.Add($"{nameof(GameConstants)} gameConstants");
                    }
                    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))
                {
                    string gameConstantsStr;
                    if (objData.GameReleaseOptions == null)
                    {
                        gameConstantsStr = $"{nameof(GameConstants)}.{obj.GetObjectData().GameCategory}";
                    }
                    else
                    {
                        gameConstantsStr = "gameConstants";
                    }
                    fg.AppendLine("if (group.RecordCache.Count == 0) return;");
                    fg.AppendLine($"var cuts = group.Cut(CutCount).ToArray();");
                    fg.AppendLine($"Stream[] subStreams = new Stream[cuts.Length + 1];");
                    fg.AppendLine($"byte[] groupBytes = new byte[{gameConstantsStr}.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, {gameConstantsStr}, 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($"var bundle = new {nameof(WritingBundle)}({gameConstantsStr})");
                        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(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 GenerateCopyIn(
            FileGeneration fg,
            ObjectGeneration objGen,
            TypeGeneration typeGen,
            Accessor readerAccessor,
            Accessor itemAccessor,
            Accessor errorMaskAccessor,
            Accessor translationAccessor)
        {
            GenderedType gender = typeGen as GenderedType;
            var          data   = typeGen.GetFieldData();

            if (!this.Module.TryGetTypeGeneration(gender.SubTypeGeneration.GetType(), out var subTransl))
            {
                throw new ArgumentException("Unsupported type generator: " + gender.SubTypeGeneration);
            }

            if (data.RecordType.HasValue)
            {
                fg.AppendLine($"{readerAccessor}.Position += {readerAccessor}.{nameof(MutagenBinaryReadStream.MetaData)}.{nameof(ParsingBundle.Constants)}.{nameof(GameConstants.SubConstants)}.{nameof(RecordHeaderConstants.HeaderLength)};");
            }
            else if (data.MarkerType.HasValue && !gender.MarkerPerGender)
            {
                fg.AppendLine($"{readerAccessor}.Position += {readerAccessor}.{nameof(MutagenBinaryReadStream.MetaData)}.{nameof(ParsingBundle.Constants)}.{nameof(GameConstants.SubConstants)}.{nameof(RecordHeaderConstants.HeaderLength)} + contentLength; // Skip marker");
            }

            bool notNull = gender.ItemNullable && !gender.SubTypeGeneration.IsNullable;

            using (var args = new ArgsWrapper(fg,
                                              $"{itemAccessor} = {this.NamespacePrefix}GenderedItemBinaryTranslation.Parse{(gender.MarkerPerGender ? "MarkerPerItem" : null)}<{gender.SubTypeGeneration.TypeName(getter: false, needsCovariance: true)}>"))
            {
                args.AddPassArg($"frame");
                if (gender.MaleMarker.HasValue)
                {
                    args.Add($"maleMarker: {objGen.RecordTypeHeaderName(gender.MaleMarker.Value)}");
                    args.Add($"femaleMarker: {objGen.RecordTypeHeaderName(gender.FemaleMarker.Value)}");
                }
                if (data.MarkerType.HasValue && gender.MarkerPerGender)
                {
                    args.Add($"marker: {objGen.RecordTypeHeaderName(data.MarkerType.Value)}");
                }
                var subData = gender.SubTypeGeneration.GetFieldData();
                if (subData.RecordType.HasValue &&
                    !(gender.SubTypeGeneration is LoquiType))
                {
                    args.Add($"contentMarker: {objGen.RecordTypeHeaderName(subData.RecordType.Value)}");
                }
                LoquiType loqui = gender.SubTypeGeneration as LoquiType;
                if (loqui != null)
                {
                    if (subData?.RecordTypeConverter != null &&
                        subData.RecordTypeConverter.FromConversions.Count > 0)
                    {
                        args.Add($"parseParams: {objGen.RegistrationName}.{typeGen.Name}Converter");
                    }
                }
                if (gender.FemaleConversions != null)
                {
                    args.Add($"femaleRecordConverter: {objGen.RegistrationName}.{typeGen.Name}FemaleConverter");
                }
                if (gender.MaleConversions != null)
                {
                    args.Add($"maleRecordConverter: {objGen.RegistrationName}.{typeGen.Name}MaleConverter");
                }

                bool needsRecordConv = gender.SubTypeGeneration.NeedsRecordConverter();
                if (subTransl.AllowDirectParse(objGen, gender.SubTypeGeneration, false))
                {
                    if (loqui != null)
                    {
                        args.Add($"transl: {loqui.ObjectTypeName}{loqui.GenericTypes(getter: false)}.TryCreateFromBinary");
                    }
                    else
                    {
                        args.Add($"transl: {subTransl.GetTranslatorInstance(gender.SubTypeGeneration, getter: false)}.Parse");
                        if (gender.ItemNullable)
                        {
                            args.Add($"skipMarker: false");
                        }
                    }
                }
                else
                {
                    args.Add(gen =>
                    {
                        gen.AppendLine($"transl: (MutagenFrame r, out {gender.SubTypeGeneration.TypeName(getter: false, needsCovariance: true)} genSubItem{(needsRecordConv ? $", {nameof(RecordTypeConverter)}? conv" : null)}) =>");
                        using (new BraceWrapper(gen))
                        {
                            subTransl.GenerateCopyInRet(
                                fg: gen,
                                objGen: objGen,
                                targetGen: gender.SubTypeGeneration,
                                typeGen: gender.SubTypeGeneration,
                                readerAccessor: "r",
                                translationAccessor: null,
                                retAccessor: "return ",
                                outItemAccessor: new Accessor("genSubItem"),
                                asyncMode: AsyncMode.Off,
                                errorMaskAccessor: "listErrMask",
                                converterAccessor: "conv",
                                inline: false);
                        }
                        if (gender.ItemNullable)
                        {
                            args.Add($"skipMarker: false");
                        }
                    });
                }
                if (notNull)
                {
                    args.Add($"fallback: {gender.SubTypeGeneration.GetDefault(getter: false)}");
                }
            }
        }
示例#30
0
 public bool IsUnknownGeneric(LoquiType type)
 {
     return(type.RefType != LoquiRefType.Direct &&
            type.TargetObjectGeneration == null);
 }