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); }
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); } } }
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; }
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)); }
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); }
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); }
public NamespaceManagerGenerator(NamespaceWrapper nsw) { this.namespaceWrapper = nsw; }
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); }
public RelationGenerator(RelationNode relationNode, NamespaceWrapper namespaceWrapper) { this.relationNode = relationNode; this.namespaceWrapper = namespaceWrapper; }
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); }
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); } }