Beispiel #1
0
        string GenerateNestedXpathCode(string[] xpathArray, CodeMemberMethod saveMethod)
        {
            string currentName = "myElement";
            //XmlElement connectionsElement = parentDocument.CreateElement("Connections");
            //parentNode.AppendChild(connectionsElement);
            CodeVariableReferenceExpression parentDocument = new CodeVariableReferenceExpression("parentDocument");
            CodeTypeReference xmlElement = new CodeTypeReference("XmlElement");

            for (int i = 0; i < xpathArray.Length - 1; i++)
            {
                string lowerName = NamespaceWrapper.GetXpathFromQualifiedName(xpathArray[i]);
                lowerName = lowerName.Substring(0, 1).ToLower() + lowerName.Substring(1) + "Element";
                CodeMethodInvokeExpression       createElement  = new CodeMethodInvokeExpression(parentDocument, "CreateElement", new CodePrimitiveExpression(xpathArray[i]));
                CodeVariableDeclarationStatement newElementDecl = new CodeVariableDeclarationStatement(xmlElement, lowerName, createElement);
                saveMethod.Statements.Add(newElementDecl);

                CodeVariableReferenceExpression newElement    = new CodeVariableReferenceExpression(lowerName);
                CodeVariableReferenceExpression parentElement = new CodeVariableReferenceExpression(currentName);
                CodeMethodInvokeExpression      appendChild   = new CodeMethodInvokeExpression(parentElement, "AppendChild", newElement);
                saveMethod.Statements.Add(appendChild);

                currentName = lowerName;
            }

            return(currentName);
        }
Beispiel #2
0
        private static IReadOnlyCollection <MemberDeclarationSyntax> Generate(NamespaceWrapper root, ISet <string> excludeMembersAttributes, ISet <string> excludeAttributes, Nullability currentNullability, Func <TypeWrapper, bool> excludeFunc)
        {
            var namespaces = GetAllNamespaces(root)
                             .AsParallel()
                             .Select(namespaceInfo =>
                                     (namespaceInfo, members: namespaceInfo
                                      .Members
                                      .OrderByAndExclude(excludeMembersAttributes, excludeAttributes)
                                      .Where(x => !x.IsNested)
                                      .ToList()))
                             .Where(x => x.members.Count > 0)
                             .OrderBy(x => x.namespaceInfo.FullName)
                             .ToList();

            var output = new List <MemberDeclarationSyntax> [namespaces.Count];

            Parallel.For(
                0,
                namespaces.Count,
                namespaceIndex =>
            {
                var(namespaceInfo, types) = namespaces[namespaceIndex];

                if (types.Count == 0)
                {
                    return;
                }

                var list = new List <MemberDeclarationSyntax>(types.Count);
                output[namespaceIndex] = list;

                var members = new MemberDeclarationSyntax?[types.Count];

                Parallel.For(
                    0,
                    types.Count,
                    i =>
                {
                    var current = types[i];
                    var member  = Generate(current, excludeMembersAttributes, excludeAttributes, excludeFunc, currentNullability, 1);

                    if (member != null)
                    {
                        members[i] = member.AddTrialingNewLines().AddLeadingNewLines(i == 0 ? 1 : 0);
                    }
                });

                var namespaceName = namespaceInfo.FullName;

                var validMembers = members.Where(x => x != null).Select(x => x !).ToList();
                if (string.IsNullOrEmpty(namespaceName))
                {
                    list.AddRange(validMembers);
                }
                else
                {
                    list.Add(NamespaceDeclaration(namespaceName, validMembers, namespaceIndex != 0));
                }
            });
		public void VisitTypeDefinitionCollection(Mono.Collections.Generic.Collection<TypeDefinition> types)
		{
			foreach (TypeDefinition typedef in types)
			{
                if ((typedef.Attributes & TypeAttributes.VisibilityMask) <= TypeAttributes.Public)
				{
                    NamespaceWrapper wrapper = new NamespaceWrapper(typedef.Module, typedef.Namespace);
                    AppendNode(typedef.Module, wrapper, true);
                    AppendNode(wrapper, typedef, true);
				}
			}
		}
Beispiel #4
0
        public ClassGenerator(TableNode tableNode)
        {
            this.tableNode = tableNode;
            Database database = ((DatabaseNode)tableNode.Parent).Database;

            this.generateXmlConstructor = database.IsXmlSchema;
            if (this.generateXmlConstructor)
            {
                this.namespaceWrapper = (NamespaceWrapper)database.DataSet.ExtendedProperties["namespacewrapper"];
            }
            this.targetLanguage = ApplicationController.Instance.AssemblyNode.Assembly.TargetLanguage;
        }
Beispiel #5
0
        public void GenerateModGameCategoryRegistration(ObjectGeneration obj, FileGeneration fg)
        {
            using (var ns = new NamespaceWrapper(fg, $"Mutagen.Bethesda.{obj.GetObjectData().GameCategory}.Internals", fileScoped: false))
            {
                using (var c = new ClassWrapper(fg, $"{obj.Name}_Registration"))
                {
                    c.Partial = true;
                    c.Interfaces.Add(nameof(IModRegistration));
                }

                using (new BraceWrapper(fg))
                {
                    fg.AppendLine($"public {nameof(GameCategory)} GameCategory => {nameof(GameCategory)}.{obj.GetObjectData().GameCategory};");
                }
                fg.AppendLine();
            }
        }
        // TODO: check if this works
        private NamespaceWrapper Split(IEnumerable <NamespaceWrapper> parent, int level)
        {
            NamespaceWrapper         bottom = parent.SingleOrDefault(p => p.Identifiers.Length == level + 1);
            NamespaceDeclarationNode node;
            NamespaceDeclarationNode declaration;
            List <NamespaceWrapper>  deeper;

            if (bottom != null)
            {
                declaration = new NamespaceDeclarationNode(bottom.Identifiers[level]);
                node        = bottom.Node;

                foreach (var c in node.Members)
                {
                    declaration.Members.Add(c);
                }
                foreach (var c in node.Children)
                {
                    declaration.Children.Add(c);
                }
                deeper = parent.Except(new NamespaceWrapper[] { bottom }).ToList();
            }
            else
            {
                NamespaceWrapper first = parent.First();
                declaration = new NamespaceDeclarationNode(first.Identifiers[level]);
                node        = first.Node;
                deeper      = parent.ToList();
            }

            while (deeper.Count > 0)
            {
                var commonParent = deeper.Where(d => d.Identifiers[level + 1] == deeper[0].Identifiers[level + 1]).ToArray();
                var split        = Split(commonParent, level + 1);
                declaration.Members.Add(split.Node);

                foreach (var w in commonParent)
                {
                    deeper.Remove(w);
                }
            }

            return(new NamespaceWrapper(declaration));
        }
Beispiel #7
0
        public override async Task FinalizeGeneration(ProtocolGeneration proto)
        {
            if (proto.Protocol.Namespace.Equals("Bethesda"))
            {
                return;
            }
            bool           generate = false;
            FileGeneration fg       = new FileGeneration();

            var modObj = proto.ObjectGenerationsByID.Values.FirstOrDefault(o => o.GetObjectType() == ObjectType.Mod);

            fg.AppendLine("using System.Collections.Generic;");
            fg.AppendLine("using Mutagen.Bethesda.Plugins.Cache;");
            fg.AppendLine("using Mutagen.Bethesda.Plugins.Order;");
            fg.AppendLine("using Mutagen.Bethesda.Plugins.Order.Internals;");
            fg.AppendLine();
            using (var n = new NamespaceWrapper(fg, proto.DefaultNamespace))
            {
                using (var c = new ClassWrapper(fg, "TypeOptionSolidifierMixIns"))
                {
                    c.Static = true;
                }
                using (new BraceWrapper(fg))
                {
                    using (new RegionWrapper(fg, "Normal"))
                    {
                        foreach (var obj in proto.ObjectGenerationsByName
                                 .OrderBy(x => x.Key)
                                 .Select(x => x.Value))
                        {
                            if (!await obj.IsMajorRecord())
                            {
                                continue;
                            }

                            var topLevel = modObj.Fields.Any(x =>
                            {
                                if (x is not GroupType grup)
                                {
                                    return(false);
                                }
                                var grupTarget = grup.GetGroupTarget();
                                if (grupTarget == obj)
                                {
                                    return(true);
                                }
                                return(obj.BaseClassTrail().Any(b => b == grupTarget));
                            });
                            var topLevelStr = topLevel ? "TopLevel" : string.Empty;

                            using (var comment = new CommentWrapper(fg))
                            {
                                comment.Summary.AppendLine($"Scope a load order query to {obj.Name}");
                                comment.Parameters.GetOrAdd("listings").AppendLine("ModListings to query");
                                comment.Return.AppendLine($"A typed object to do further queries on {obj.Name}");
                            }
                            using (var args = new FunctionWrapper(fg,
                                                                  $"public static {topLevelStr}TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {obj.Interface(getter: false)}, {obj.Interface(getter: true)}> {obj.Name}"))
                            {
                                args.Add($"this IEnumerable<IModListingGetter<I{proto.Protocol.Namespace}ModGetter>> listings");
                            }
                            using (new BraceWrapper(fg))
                            {
                                using (var args = new ArgsWrapper(fg,
                                                                  $"return new {topLevelStr}TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {obj.Interface(getter: false)}, {obj.Interface(getter: true)}>"))
                                {
                                    args.Add($"(bool includeDeletedRecords) => listings.WinningOverrides<{obj.Interface(getter: true)}>(includeDeletedRecords: includeDeletedRecords)");
                                    args.Add($"({nameof(ILinkCache)} linkCache, bool includeDeletedRecords) => listings.WinningOverrideContexts<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {obj.Interface(getter: false)}, {obj.Interface(getter: true)}>(linkCache, includeDeletedRecords: includeDeletedRecords)");
                                }
                            }
                            fg.AppendLine();

                            using (var comment = new CommentWrapper(fg))
                            {
                                comment.Summary.AppendLine($"Scope a load order query to {obj.Name}");
                                comment.Parameters.GetOrAdd("mods").AppendLine("Mods to query");
                                comment.Return.AppendLine($"A typed object to do further queries on {obj.Name}");
                            }
                            using (var args = new FunctionWrapper(fg,
                                                                  $"public static {topLevelStr}TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {obj.Interface(getter: false)}, {obj.Interface(getter: true)}> {obj.Name}"))
                            {
                                args.Add($"this IEnumerable<I{proto.Protocol.Namespace}ModGetter> mods");
                            }
                            using (new BraceWrapper(fg))
                            {
                                using (var args = new ArgsWrapper(fg,
                                                                  $"return new {topLevelStr}TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {obj.Interface(getter: false)}, {obj.Interface(getter: true)}>"))
                                {
                                    args.Add($"(bool includeDeletedRecords) => mods.WinningOverrides<{obj.Interface(getter: true)}>(includeDeletedRecords: includeDeletedRecords)");
                                    args.Add($"({nameof(ILinkCache)} linkCache, bool includeDeletedRecords) => mods.WinningOverrideContexts<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {obj.Interface(getter: false)}, {obj.Interface(getter: true)}>(linkCache, includeDeletedRecords: includeDeletedRecords)");
                                }
                            }
                            fg.AppendLine();
                            generate = true;
                        }
                    }

                    using (new RegionWrapper(fg, "Link Interfaces"))
                    {
                        if (LinkInterfaceModule.ObjectMappings.TryGetValue(proto.Protocol, out var interfs))
                        {
                            foreach (var interf in interfs)
                            {
                                var getter = $"{interf.Key}Getter";
                                using (var comment = new CommentWrapper(fg))
                                {
                                    comment.Summary.AppendLine($"Scope a load order query to {interf.Key}");
                                    comment.Parameters.GetOrAdd("listings").AppendLine("ModListings to query");
                                    comment.Return.AppendLine($"A typed object to do further queries on {interf.Key}");
                                }
                                using (var args = new FunctionWrapper(fg,
                                                                      $"public static TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {interf.Key}, {getter}> {interf.Key}"))
                                {
                                    args.Add($"this IEnumerable<IModListingGetter<I{proto.Protocol.Namespace}ModGetter>> listings");
                                }
                                using (new BraceWrapper(fg))
                                {
                                    using (var args = new ArgsWrapper(fg,
                                                                      $"return new TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {interf.Key}, {getter}>"))
                                    {
                                        args.Add($"(bool includeDeletedRecords) => listings.WinningOverrides<{getter}>(includeDeletedRecords: includeDeletedRecords)");
                                        args.Add($"({nameof(ILinkCache)} linkCache, bool includeDeletedRecords) => listings.WinningOverrideContexts<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {interf.Key}, {getter}>(linkCache, includeDeletedRecords: includeDeletedRecords)");
                                    }
                                }
                                fg.AppendLine();

                                using (var comment = new CommentWrapper(fg))
                                {
                                    comment.Summary.AppendLine($"Scope a load order query to {interf.Key}");
                                    comment.Parameters.GetOrAdd("mods").AppendLine("Mods to query");
                                    comment.Return.AppendLine($"A typed object to do further queries on {interf.Key}");
                                }
                                using (var args = new FunctionWrapper(fg,
                                                                      $"public static TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {interf.Key}, {getter}> {interf.Key}"))
                                {
                                    args.Add($"this IEnumerable<I{proto.Protocol.Namespace}ModGetter> mods");
                                }
                                using (new BraceWrapper(fg))
                                {
                                    using (var args = new ArgsWrapper(fg,
                                                                      $"return new TypedLoadOrderAccess<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {interf.Key}, {getter}>"))
                                    {
                                        args.Add($"(bool includeDeletedRecords) => mods.WinningOverrides<{getter}>(includeDeletedRecords: includeDeletedRecords)");
                                        args.Add($"({nameof(ILinkCache)} linkCache, bool includeDeletedRecords) => mods.WinningOverrideContexts<I{proto.Protocol.Namespace}Mod, I{proto.Protocol.Namespace}ModGetter, {interf.Key}, {getter}>(linkCache, includeDeletedRecords: includeDeletedRecords)");
                                    }
                                }
                                fg.AppendLine();
                            }
                        }
                    }
                }
            }

            if (!generate)
            {
                return;
            }
            var path = Path.Combine(proto.DefFileLocation.FullName, $"TypeSolidifier{Loqui.Generation.Constants.AutogeneratedMarkerString}.cs");

            fg.Generate(path);
            proto.GeneratedFiles.Add(path, ProjItemType.Compile);
        }
Beispiel #8
0
        public override async Task FinalizeGeneration(ProtocolGeneration proto)
        {
            if (proto.Protocol.Namespace.Equals("Bethesda"))
            {
                return;
            }

            var objData = proto.ObjectGenerationsByID.Values.FirstOrDefault()?.GetObjectData();

            if (objData == null)
            {
                return;
            }

            var relString = objData.HasMultipleReleases ? "release.ToGameRelease()" : $"{nameof(GameRelease)}.{proto.Protocol.Namespace}";

            FileGeneration fg = new FileGeneration();

            fg.AppendLine("using System.Collections.Generic;");
            fg.AppendLine($"using Mutagen.Bethesda.Plugins;");
            fg.AppendLine($"using Mutagen.Bethesda.Plugins.Implicit;");
            fg.AppendLine($"using Mutagen.Bethesda.{proto.Protocol.Namespace};");
            fg.AppendLine();
            using (var n = new NamespaceWrapper(fg, "Mutagen.Bethesda"))
            {
                using (var c = new ClassWrapper(fg, "ImplicitsMixIn"))
                {
                    c.Static = true;
                }
                using (new BraceWrapper(fg))
                {
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static IReadOnlyCollection<ModKey> {proto.Protocol.Namespace}"))
                    {
                        args.Add($"this ImplicitBaseMasters _");
                        if (objData.HasMultipleReleases)
                        {
                            args.Add($"{objData.GameCategory}Release release");
                        }
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return Implicits.Get({relString}).BaseMasters;");
                    }
                    fg.AppendLine();

                    using (var args = new FunctionWrapper(fg,
                                                          $"public static IReadOnlyCollection<ModKey> {proto.Protocol.Namespace}"))
                    {
                        args.Add($"this ImplicitListings _");
                        if (objData.HasMultipleReleases)
                        {
                            args.Add($"{objData.GameCategory}Release release");
                        }
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return Implicits.Get({relString}).Listings;");
                    }
                    fg.AppendLine();

                    using (var args = new FunctionWrapper(fg,
                                                          $"public static IReadOnlyCollection<FormKey> {proto.Protocol.Namespace}"))
                    {
                        args.Add($"this ImplicitRecordFormKeys _");
                        if (objData.HasMultipleReleases)
                        {
                            args.Add($"{objData.GameCategory}Release release");
                        }
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return Implicits.Get({relString}).RecordFormKeys;");
                    }
                }
            }

            var path = Path.Combine(proto.DefFileLocation.FullName, $"../ImplicitsMixIn{Loqui.Generation.Constants.AutogeneratedMarkerString}.cs");

            fg.Generate(path);
            proto.GeneratedFiles.Add(path, ProjItemType.Compile);
        }
        public override async Task FinalizeGeneration(ProtocolGeneration proto)
        {
            if (proto.Protocol.Namespace.Equals("All") ||
                proto.Protocol.Namespace.Equals("Bethesda"))
            {
                return;
            }
            FileGeneration fg = new FileGeneration();

            fg.AppendLine("using System.Collections.Generic;");
            fg.AppendLine("using Mutagen.Bethesda.Plugins.Order;");
            fg.AppendLine("using Mutagen.Bethesda.Cache.Implementations;");

            fg.AppendLine();
            using (var n = new NamespaceWrapper(fg, proto.DefaultNamespace))
            {
                var setterName = $"I{proto.Protocol.Namespace}Mod";
                var getterName = $"I{proto.Protocol.Namespace}ModGetter";
                var generic    = $"<{setterName}, {getterName}>";
                using (var c = new ClassWrapper(fg, "LinkCacheMixIns"))
                {
                    c.Static = true;
                }
                using (new BraceWrapper(fg))
                {
                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a Link Cache using a single mod as its link target. <br/>");
                        comment.Summary.AppendLine($"Modification of the target Mod is not safe.  Internal caches can become incorrect if ");
                        comment.Summary.AppendLine($"modifications occur on content already cached.");
                        comment.Parameters.GetOrAdd("mod").AppendLine("Mod to construct the package relative to");
                        comment.Return.AppendLine($"LinkPackage attached to given mod");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static ImmutableModLinkCache{generic} ToImmutableLinkCache"))
                    {
                        args.Add($"this {getterName} mod");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return mod.ToImmutableLinkCache{generic}();");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a Link Cache using a single mod as its link target.  Mod is allowed to be modified afterwards, but");
                        comment.Summary.AppendLine($"this comes at a performance cost of not allowing much caching to be done.  If the mod is not expected to");
                        comment.Summary.AppendLine($"be modified afterwards, use ImmutableModLinkCache instead.<br/>");
                        comment.Parameters.GetOrAdd("mod").AppendLine("Mod to construct the package relative to");
                        comment.Return.AppendLine($"LinkPackage attached to given mod");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static MutableModLinkCache{generic} ToMutableLinkCache"))
                    {
                        args.Add($"this {getterName} mod");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return mod.ToMutableLinkCache{generic}();");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a new linking package relative to a load order.<br/>");
                        comment.Summary.AppendLine($"Will resolve links to the highest overriding mod containing the record being sought. <br/>");
                        comment.Summary.AppendLine($"Modification of the target LoadOrder, or Mods on the LoadOrder is not safe.  Internal caches can become");
                        comment.Summary.AppendLine($"incorrect if modifications occur on content already cached.");
                        comment.Parameters.GetOrAdd("loadOrder").AppendLine("LoadOrder to construct the package relative to");
                        comment.Return.AppendLine($"LinkPackage attached to given LoadOrder");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static ImmutableLoadOrderLinkCache{generic} ToImmutableLinkCache"))
                    {
                        args.Add($"this ILoadOrderGetter<{getterName}> loadOrder");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return loadOrder.ToImmutableLinkCache{generic}();");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a new linking package relative to a load order.<br/>");
                        comment.Summary.AppendLine($"Will resolve links to the highest overriding mod containing the record being sought. <br/>");
                        comment.Summary.AppendLine($"Modification of the target LoadOrder, or Mods on the LoadOrder is not safe.  Internal caches can become");
                        comment.Summary.AppendLine($"incorrect if modifications occur on content already cached.");
                        comment.Parameters.GetOrAdd("loadOrder").AppendLine("LoadOrder to construct the package relative to");
                        comment.Return.AppendLine($"LinkPackage attached to given LoadOrder");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static ImmutableLoadOrderLinkCache{generic} ToImmutableLinkCache"))
                    {
                        args.Add($"this ILoadOrderGetter<IModListingGetter<{getterName}>> loadOrder");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return loadOrder.ToImmutableLinkCache{generic}();");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a new linking package relative to a load order.<br/>");
                        comment.Summary.AppendLine($"Will resolve links to the highest overriding mod containing the record being sought. <br/>");
                        comment.Summary.AppendLine($"Modification of the target LoadOrder, or Mods on the LoadOrder is not safe.  Internal caches can become");
                        comment.Summary.AppendLine($"incorrect if modifications occur on content already cached.");
                        comment.Parameters.GetOrAdd("loadOrder").AppendLine("LoadOrder to construct the package relative to");
                        comment.Return.AppendLine($"LinkPackage attached to given LoadOrder");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static ImmutableLoadOrderLinkCache{generic} ToImmutableLinkCache"))
                    {
                        args.Add($"this IEnumerable<IModListingGetter<{getterName}>> loadOrder");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return loadOrder.ToImmutableLinkCache{generic}();");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a new linking package relative to a load order.<br/>");
                        comment.Summary.AppendLine($"Will resolve links to the highest overriding mod containing the record being sought. <br/>");
                        comment.Summary.AppendLine($"Modification of the target LoadOrder, or Mods on the LoadOrder is not safe.  Internal caches can become");
                        comment.Summary.AppendLine($"incorrect if modifications occur on content already cached.");
                        comment.Parameters.GetOrAdd("loadOrder").AppendLine("LoadOrder to construct the package relative to");
                        comment.Return.AppendLine($"LinkPackage attached to given LoadOrder");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static ImmutableLoadOrderLinkCache{generic} ToImmutableLinkCache"))
                    {
                        args.Add($"this IEnumerable<{getterName}> loadOrder");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return loadOrder.ToImmutableLinkCache{generic}();");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a mutable load order link cache by combining an existing immutable load order cache,");
                        comment.Summary.AppendLine($"plus a set of mods to be put at the end of the load order and allow to be mutable.");
                        comment.Parameters.GetOrAdd("immutableBaseCache").AppendLine("LoadOrderCache to use as the immutable base");
                        comment.Parameters.GetOrAdd("mutableMods").AppendLine("Set of mods to place at the end of the load order, which are allowed to be modified afterwards");
                        comment.Return.AppendLine($"LinkPackage attached to given LoadOrder");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static MutableLoadOrderLinkCache{generic} ToMutableLinkCache"))
                    {
                        args.Add($"this ILoadOrderGetter<{getterName}> immutableBaseCache");
                        args.Add($"params {setterName}[] mutableMods");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return immutableBaseCache.ToMutableLinkCache{generic}(mutableMods);");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a mutable load order link cache by combining an existing immutable load order cache,");
                        comment.Summary.AppendLine($"plus a set of mods to be put at the end of the load order and allow to be mutable.");
                        comment.Parameters.GetOrAdd("immutableBaseCache").AppendLine("LoadOrderCache to use as the immutable base");
                        comment.Parameters.GetOrAdd("mutableMods").AppendLine("Set of mods to place at the end of the load order, which are allowed to be modified afterwards");
                        comment.Return.AppendLine($"LinkPackage attached to given LoadOrder");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static MutableLoadOrderLinkCache{generic} ToMutableLinkCache"))
                    {
                        args.Add($"this ILoadOrderGetter<IModListingGetter<{getterName}>> immutableBaseCache");
                        args.Add($"params {setterName}[] mutableMods");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return immutableBaseCache.ToMutableLinkCache{generic}(mutableMods);");
                    }
                    fg.AppendLine();

                    using (var comment = new CommentWrapper(fg))
                    {
                        comment.Summary.AppendLine($"Creates a mutable load order link cache by combining an existing immutable load order cache,");
                        comment.Summary.AppendLine($"plus a set of mods to be put at the end of the load order and allow to be mutable.");
                        comment.Parameters.GetOrAdd("immutableBaseCache").AppendLine("LoadOrderCache to use as the immutable base");
                        comment.Parameters.GetOrAdd("mutableMods").AppendLine("Set of mods to place at the end of the load order, which are allowed to be modified afterwards");
                        comment.Return.AppendLine($"LinkPackage attached to given LoadOrder");
                    }
                    using (var args = new FunctionWrapper(fg,
                                                          $"public static MutableLoadOrderLinkCache{generic} ToMutableLinkCache"))
                    {
                        args.Add($"this IEnumerable<{getterName}> immutableBaseCache");
                        args.Add($"params {setterName}[] mutableMods");
                    }
                    using (new BraceWrapper(fg))
                    {
                        fg.AppendLine($"return immutableBaseCache.ToMutableLinkCache{generic}(mutableMods);");
                    }
                    fg.AppendLine();
                }
            }

            var path = Path.Combine(proto.DefFileLocation.FullName, $"LinkCacheMixIns{Loqui.Generation.Constants.AutogeneratedMarkerString}.cs");

            fg.Generate(path);
            proto.GeneratedFiles.Add(path, ProjItemType.Compile);
        }
        /// <summary>
        ///     Main executor function.
        /// </summary>
        /// <returns>A CodeCompileUnit.</returns>
        public CodeCompileUnit Execute()
        {
            var codeCompileUnit = new CodeCompileUnit();

            // Set namespace
            var nsWrap = new NamespaceWrapper(new CodeNamespace(_codeNamespace));

            // Set class
            var codeClass = new CodeTypeDeclaration(_schemaDocument.Title)
            {
                Attributes = MemberAttributes.Public
            };
            var clWrap = new ClassWrapper(codeClass);

            // Add imports for interfaces and dependencies
            nsWrap.AddImportsFromWrapper(_schemaWrapper);

            // Add comments and attributes for class
            if (!String.IsNullOrEmpty(_schemaDocument.Description))
            {
                clWrap.AddComment(_schemaDocument.Description);
            }

            // Add extended class
            if (_schemaDocument.Extends != null && _schemaDocument.Extends.Count > 0)
            {
                clWrap.AddInterface(JsonSchemaUtils.GetType(_schemaDocument.Extends[0], _codeNamespace).Name);
            }

            // Add interfaces
            foreach (Type t in _schemaWrapper.Interfaces)
            {
                clWrap.AddInterface(t.Name);
            }

            // Add properties with getters/setters
            if (_schemaDocument.Properties != null)
            {
                foreach (var i in _schemaDocument.Properties)
                {
                    JsonSchema schema = i.Value;

                    // Sanitize inputs
                    if (!String.IsNullOrEmpty(schema.Description))
                    {
                        schema.Description = Regex.Unescape(schema.Description);
                    }

                    // If it is an enum
                    var propertyName = i.Key.Capitalize();
                    if (schema.Enum != null)
                    {
                        var enumField = new CodeTypeDeclaration(propertyName);
                        var enumWrap  = new EnumWrapper(enumField);

                        // Add comment if not null
                        if (!String.IsNullOrEmpty(schema.Description))
                        {
                            enumField.Comments.Add(new CodeCommentStatement(schema.Description));
                        }

                        foreach (JToken j in schema.Enum)
                        {
                            enumWrap.AddMember(j.ToString().SanitizeIdentifier());
                        }

                        // Add to namespace
                        nsWrap.AddClass(enumWrap.Property);
                    }
                    else
                    {
                        // WARNING: This assumes the namespace of the property is the same as the parent.
                        // This should not be a problem since imports are handled for all dependencies at the beginning.
                        Type   type         = JsonSchemaUtils.GetType(schema, _codeNamespace);
                        bool   isCustomType = type.Namespace != null && type.Namespace.Equals(_codeNamespace);
                        string strType      = String.Empty;

                        // Add imports
                        nsWrap.AddImport(type.Namespace);
                        nsWrap.AddImportsFromSchema(schema);

                        // Get the property type
                        if (isCustomType)
                        {
                            strType = JsonSchemaUtils.IsArray(schema) ? string.Format("{0}<{1}>", JsonSchemaUtils.GetArrayType(schema), type.Name) : type.Name;
                        }
                        else if (JsonSchemaUtils.IsArray(schema))
                        {
                            strType = string.Format("{0}<{1}>", JsonSchemaUtils.GetArrayType(schema),
                                                    new CSharpCodeProvider().GetTypeOutput(new CodeTypeReference(type)));
                        }

                        //var field = new CodeMemberField
                        //{
                        //    Attributes = MemberAttributes.Private,
                        //    Name = "_" + i.Key,
                        //    Type =
                        //        TypeUtils.IsPrimitive(type) && !JsonSchemaUtils.IsArray(schema)
                        //            ? new CodeTypeReference(type)
                        //            : new CodeTypeReference(strType)
                        //};


                        //clWrap.Property.Members.Add(field);

                        var property = CreateProperty(propertyName, TypeUtils.IsPrimitive(type) && !JsonSchemaUtils.IsArray(schema)
                                    ? new CodeTypeReference(type)
                                    : new CodeTypeReference(strType));

                        var prWrap = new PropertyWrapper(property);

                        // Add comments and attributes
                        prWrap.Populate(schema, _attributeType);

                        // Add default, if any
                        if (schema.Default != null)
                        {
                            clWrap.AddDefault(propertyName, property.Type, schema.Default.ToString());
                        }

                        clWrap.Property.Members.Add(property);
                    }
                }
            }

            // Add class to namespace
            nsWrap.AddClass(clWrap.Property);
            codeCompileUnit.Namespaces.Add(nsWrap.Namespace);

            return(codeCompileUnit);
        }
Beispiel #11
0
 public NamespaceManagerGenerator(NamespaceWrapper nsw)
 {
     this.namespaceWrapper = nsw;
 }
Beispiel #12
0
        void AddSubelementsOfSkippedElement(TableNode parentNode, string xpath)
        {
            if (parentNode.Table.Skipped)
            {
                TableNode pparentNode = (TableNode)parentNode.UserData["parentnode"];
                string    path        = xpath + '/' + parentNode.Name;
                AddSubelementsOfSkippedElement(pparentNode, path);
                return;
                //-------
            }

            CodeCompileUnit     cunit          = (CodeCompileUnit)parentNode.UserData["cunit"];
            CodeNamespace       ns             = cunit.Namespaces[0];
            CodeTypeDeclaration persClass      = ns.Types[0];
            CodeConstructor     xmlConstructor = null;
            CodeMemberMethod    xmlSaveMethod  = null;

            foreach (CodeTypeMember member in persClass.Members)
            {
                if (member.Name == ".ctor")
                {
                    CodeConstructor cc = (CodeConstructor)member;
                    if (cc.Parameters.Count > 0)
                    {
                        xmlConstructor = cc;
                    }
                }
                else if (member.Name == "Save")
                {
                    CodeMemberMethod cmm = (CodeMemberMethod)member;
                    if (cmm.Parameters.Count == 1 && cmm.Parameters[0].Type.BaseType == "XmlNode")
                    {
                        xmlSaveMethod = cmm;
                    }
                }
                if (xmlConstructor != null && xmlSaveMethod != null)
                {
                    break;
                }
            }

            /*
             *                      XmlElement subElement = parentNode.OwnerDocument.CreateElement("MyElement");
             *                      newElement.AppendChild(subElement);
             *                      newElement = subElement;
             */
            int    p           = xpath.LastIndexOf(':');
            string namespc     = this.namespaceWrapper[NamespaceWrapper.GetPrefixFromQualifiedName(xpath)];
            string elementName = NamespaceWrapper.GetXpathFromQualifiedName(xpath);

            CodePrimitiveExpression         myElementName = new CodePrimitiveExpression(elementName);
            CodePrimitiveExpression         myNamespace   = new CodePrimitiveExpression(namespc);
            CodeVariableReferenceExpression newElement    = new CodeVariableReferenceExpression("myElement");
            CodeVariableReferenceExpression subElement    = new CodeVariableReferenceExpression("subElement");
            CodeVariableReferenceExpression ownerDoc      = new CodeVariableReferenceExpression("parentNode.OwnerDocument");
            CodeMethodInvokeExpression      createElementCall;

            if (namespc != null)
            {
                createElementCall = new CodeMethodInvokeExpression(ownerDoc, "CreateElement", myElementName, myNamespace);
            }
            else
            {
                createElementCall = new CodeMethodInvokeExpression(ownerDoc, "CreateElement", myElementName);
            }
            CodeVariableDeclarationStatement newElementAssign = new CodeVariableDeclarationStatement(new CodeTypeReference("XmlElement"), "subElement", createElementCall);

            xmlSaveMethod.Statements.Add(newElementAssign);

            CodeMethodInvokeExpression appendChild = new CodeMethodInvokeExpression(newElement, "AppendChild", subElement);

            xmlSaveMethod.Statements.Add(appendChild);

            CodeAssignStatement backAssign = new CodeAssignStatement(newElement, subElement);

            xmlSaveMethod.Statements.Add(backAssign);

            /*
             * xmlNode = xmlNode.SelectSingleNode("xpath");
             */
            CodeVariableReferenceExpression xmlNode       = new CodeVariableReferenceExpression("xmlNode");
            CodePrimitiveExpression         xPathExpr     = new CodePrimitiveExpression(xpath);
            CodeVariableReferenceExpression nsManager     = new CodeVariableReferenceExpression("NamespaceManager");
            CodePropertyReferenceExpression nsInstance    = new CodePropertyReferenceExpression(nsManager, "Instance");
            CodeMethodInvokeExpression      selectNodes   = new CodeMethodInvokeExpression(xmlNode, "SelectSingleNode", xPathExpr, nsInstance);
            CodeAssignStatement             xmlNodeAssign = new CodeAssignStatement(xmlNode, selectNodes);

            xmlConstructor.Statements.Add(xmlNodeAssign);

            GenerateMembers(persClass, xmlConstructor, xmlSaveMethod);


            // xmlNode = xmlNode.ParentNode;
            CodePropertyReferenceExpression parentNodeProperty = new CodePropertyReferenceExpression(xmlNode, "ParentNode");

            xmlNodeAssign = new CodeAssignStatement(xmlNode, parentNodeProperty);
            xmlConstructor.Statements.Add(xmlNodeAssign);

            // newElement = (XmlElement) newElement.ParentNode;
            parentNodeProperty = new CodePropertyReferenceExpression(newElement, "ParentNode");
            CodeCastExpression xmlElementCast = new CodeCastExpression("XmlElement", parentNodeProperty);

            backAssign = new CodeAssignStatement(newElement, xmlElementCast);
            xmlSaveMethod.Statements.Add(backAssign);
        }
Beispiel #13
0
 public RelationGenerator(RelationNode relationNode, NamespaceWrapper namespaceWrapper)
 {
     this.relationNode     = relationNode;
     this.namespaceWrapper = namespaceWrapper;
 }
Beispiel #14
0
        private void GenerateXmlLoadAndSaveCode(CodeConstructor xmlConstructor, CodeMemberMethod saveToXmlMethod, Relation relation, string foreignClassShort)
        {
            /*
             *      XmlNodeList nodeList = xmlNode.SelectNodes("SubNodeName");
             *      for(int i = 0; i < nodeList.Count; i = i + 1)
             *      {
             *              XmlNode subNode = nodeList[i];
             *              this.relationField.Add(new RelatedType(subNode));
             *      }
             */
            TargetLanguage targetLanguage = ApplicationController.Instance.AssemblyNode.Assembly.TargetLanguage;
            string         xpath          = null;

            if (relation.IsForeign)
            {
                xpath = ((ForeignFkRelation)relation).XPath;
            }
            else
            {
                throw new Exception("Internal Error 132 in RelationGenerator: Relation is not a ForeignFkRelation.");
            }

            string nodeListName = relation.FieldName + "NodeList";
            CodeVariableReferenceExpression nsManager  = new CodeVariableReferenceExpression("NamespaceManager");
            CodePropertyReferenceExpression nsInstance = new CodePropertyReferenceExpression(nsManager, "Instance");

            CodeVariableDeclarationStatement nodeListDecl = new CodeVariableDeclarationStatement("XmlNodeList", nodeListName,
                                                                                                 new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("xmlNode"), "SelectNodes", new CodePrimitiveExpression(xpath), nsInstance));

            xmlConstructor.Statements.Add(nodeListDecl);

            CodeVariableReferenceExpression iExpr         = new CodeVariableReferenceExpression("i");
            CodeFieldReferenceExpression    relationField = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), relation.FieldName);

            CodeIterationStatement forLoop = new CodeIterationStatement(
                new CodeAssignStatement(iExpr, new CodePrimitiveExpression(0)),
                new CodeBinaryOperatorExpression(
                    iExpr,
                    CodeBinaryOperatorType.LessThan,
                    new CodeVariableReferenceExpression(nodeListName + ".Count")),                 // should work in C# and VB
                new CodeAssignStatement(
                    iExpr,
                    new CodeBinaryOperatorExpression(
                        iExpr,
                        CodeBinaryOperatorType.Add,
                        new CodePrimitiveExpression(1))),
                new CodeVariableDeclarationStatement("XmlNode", "subNode",
                                                     new CodeIndexerExpression(
                                                         new CodeVariableReferenceExpression(nodeListName),
                                                         iExpr)),
                new CodeExpressionStatement(
                    new CodeMethodInvokeExpression(relationField, "Add",
                                                   new CodeObjectCreateExpression(foreignClassShort,
                                                                                  new CodeVariableReferenceExpression("subNode")))));

            xmlConstructor.Statements.Add(forLoop);

            /*
             * for ( int i = 0; i < relatedContainer.Count; i = i + 1 )
             * {
             *      RelatedType relObject = relContainer[i];
             *      relObject.Save(newElement, "Elementname", "Namespace");
             * }
             */
            string elementNodeName = null;

            string[] xpathParts = xpath.Split('/');
            if (xpath.IndexOf('/') > -1)
            {
                elementNodeName = GenerateNestedXpathCode(xpathParts, saveToXmlMethod);
            }
            else
            {
                elementNodeName = "myElement";
            }

            string elementPath = xpathParts[xpathParts.Length - 1];
            string namespc     = this.namespaceWrapper[NamespaceWrapper.GetPrefixFromQualifiedName(elementPath)];

            elementPath = NamespaceWrapper.GetXpathFromQualifiedName(elementPath);

            CodeExpression namespcExpr = new CodePrimitiveExpression(namespc);

            forLoop = new CodeIterationStatement(
                new CodeAssignStatement(iExpr, new CodePrimitiveExpression(0)),
                new CodeBinaryOperatorExpression(
                    iExpr,
                    CodeBinaryOperatorType.LessThan,
                    new CodePropertyReferenceExpression(relationField, "Count")),
                new CodeAssignStatement(
                    iExpr,
                    new CodeBinaryOperatorExpression(
                        iExpr,
                        CodeBinaryOperatorType.Add,
                        new CodePrimitiveExpression(1))),
                new CodeVariableDeclarationStatement(foreignClassShort, "relObject",
                                                     new CodeIndexerExpression(relationField, iExpr)),
                new CodeExpressionStatement(
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression("relObject"), "Save",
                        new CodeVariableReferenceExpression(elementNodeName),
                        new CodePrimitiveExpression(elementPath), namespcExpr)));

            saveToXmlMethod.Statements.Add(forLoop);
        }
Beispiel #15
0
        public void GenerateCode()
        {
            this.filesWithConflicts = new List <string>();
            string          errors   = string.Empty;
            CodeDomProvider provider = null;

            if (ApplicationController.Instance.AssemblyNode.Assembly.TargetLanguage == TargetLanguage.VB)
            {
                provider            = new VBCodeProvider();
                Merge.CommentPrefix = "'";
            }
            else
            {
                provider            = new CSharpCodeProvider();
                Merge.CommentPrefix = "//";
            }

            foreach (NDOTreeNode treenode in databaseNode.Nodes)
            {
                TableNode tn = treenode as TableNode;
                if (tn == null)
                {
                    continue;
                }
                if (!tn.Table.Skipped &&
                    (tn.Table.MappingType == TableMappingType.MappedAsClass ||
                     tn.Table.MappingType == TableMappingType.MappedAsIntermediateClass))
                {
#if !DEBUG
                    try
                    {
#endif
                    string fileName = tn.Table.ClassName.ToString() + '.' + provider.FileExtension;
                    csProject.AddCsFile(fileName);
                    CodeCompileUnit cunit = new CodeCompileUnit();
                    tn.UserData.Add("cunit", cunit);
                    tn.UserData.Add("filename", Path.Combine(csProject.SourcePath, fileName));
                    new ClassGenerator(tn).GenerateCode(cunit);
#if !DEBUG
                }
                catch (Exception ex)
                {
                    errors += ex.Message + '\n';
                }
#endif
                }
            }

            if (errors != string.Empty)
            {
                goto hasErrors;
            }

            foreach (NDOTreeNode treenode in databaseNode.Nodes)
            {
                TableNode tn = treenode as TableNode;
                if (tn == null)
                {
                    continue;
                }
                if (databaseNode.Database.IsXmlSchema && tn.Table.Skipped &&
                    (tn.Table.MappingType == TableMappingType.MappedAsClass ||
                     tn.Table.MappingType == TableMappingType.MappedAsIntermediateClass))
                {
#if !DEBUG
                    try
                    {
#endif
                    new ClassGenerator(tn).AddSubelementsOfSkippedElement();
#if !DEBUG
                }
                catch (Exception ex)
                {
                    errors += ex.Message + '\n';
                }
#endif
                }
            }

            if (errors != string.Empty)
            {
                goto hasErrors;
            }


            if (this.databaseNode.Database.DataSet.ExtendedProperties.ContainsKey("namespacewrapper"))
            {
                NamespaceWrapper nsw = (NamespaceWrapper)this.databaseNode.Database.DataSet.ExtendedProperties["namespacewrapper"];
#if !DEBUG
                try
                {
#endif

                string fileName = "NamespaceManager" + "." + provider.FileExtension;

                csProject.AddCsFile(fileName);

                fileName = Path.Combine(csProject.SourcePath, fileName);

                CodeCompileUnit cunit = new CodeCompileUnit();
                new NamespaceManagerGenerator(nsw).Generate(cunit, csProject.DefaultNamespace);
                CompileAndMergeCUnit(provider, cunit, fileName);
#if !DEBUG
            }
            catch (Exception ex)
            {
                errors += ex.Message + '\n';
            }
#endif
            }



            foreach (NDOTreeNode treenode in databaseNode.Nodes)
            {
                TableNode tn = treenode as TableNode;
                if (tn == null)
                {
                    continue;
                }
                if (tn.Table.Skipped)
                {
                    continue;
                }
                if (tn.Table.MappingType == TableMappingType.NotMapped)
                {
                    continue;
                }
                if (!tn.UserData.ContainsKey("cunit"))
                {
                    continue;
                }
                CodeCompileUnit cunit    = (CodeCompileUnit)tn.UserData["cunit"];
                string          fileName = (string)tn.UserData["filename"];

                Merge.IgnoreSpaces = true;

                CompileAndMergeCUnit(provider, cunit, fileName);
            }

hasErrors:
            if (errors != string.Empty)
            {
                throw new Exception("Errors occured while generating code:\n" + errors);
            }
        }