private void WriteEnumsAndRemaps( Dictionary <string, string> remaps) { // Output the enums and the rsp entries that map parameters and fields to use // enum names var enumRemapsFileName = Path.Combine(this.EmitterGeneratedDir, "enumsRemap.rsp"); using StreamWriter enumRemapsWriter = new StreamWriter(enumRemapsFileName); enumRemapsWriter.WriteLine("--remap"); // For each enum object... foreach (var obj in this.enumObjectsFromJsons) { string foundNamespace = obj.@namespace; List <string> remapsToAdd = new List <string>(); int remapCount = 0; // For each use in an enum... foreach (var use in obj.uses) { string lookupNameForNamespace; string remapName = use.ToString(); // lookupNameForNamespace = the name to use to lookup the namespace // remapName = used in .rsp to map a param or field to use the enum if (use.@interface != null) { lookupNameForNamespace = use.@interface; } else if (use.method != null) { lookupNameForNamespace = use.method; } else { lookupNameForNamespace = use.@struct; } // If we haven't found a namespace yet, try to look it up if (string.IsNullOrEmpty(foundNamespace)) { requiredNamespaces.TryGetValue(lookupNameForNamespace, out foundNamespace); } // If we don't already have a remap entry for this param or field, add one if (!remaps.TryGetValue(remapName, out string remapValue)) { remapsToAdd.Add(remapName); remapCount++; } else { // If the existing remap wants to use this enum, keep track // so that we write the enum if (remapValue == obj.name) { remapCount++; } } } if (foundNamespace == null) { foundNamespace = "Windows.Win32.System.SystemServices"; } bool addedEnum = false; // If the enum doesn't have any remaps and isn't // an auto-populate, go to next object bool shouldWriteEnum = (remapCount != 0 || obj.autoPopulate != null); if (!shouldWriteEnum) { continue; } // Lookup the enum writer in the cache or add it if we can't find it if (!namespacesToEnumWriters.TryGetValue(foundNamespace, out var enumWriter)) { string fixedNamespaceName = foundNamespace.Replace("Windows.Win32.", string.Empty); string enumFile = Path.Combine(this.EmitterGeneratedDir, $"{fixedNamespaceName}.enums.cs"); if (File.Exists(enumFile)) { File.Delete(enumFile); } enumWriter = new EnumWriter(enumFile, foundNamespace, this.constantsHeaderText); namespacesToEnumWriters.Add(foundNamespace, enumWriter); } if (obj.name != null) { if (this.writtenConstants.ContainsKey(obj.name)) { throw new InvalidOperationException($"Tried to add enum {obj.name} but a constant with the same name already exists."); } addedEnum = enumWriter.AddEnum(obj); if (addedEnum) { if (ContainsLowerCase.IsMatch(obj.name)) { this.AddEnumWarningAndSuggestedMapping( $"Warning: {obj.name} enum contains lower case. Consider giving it an intentional name in the enums json file.", obj); } } } if (addedEnum || obj.addUsesTo != null) { var enumName = obj.name ?? obj.addUsesTo; foreach (var remap in remapsToAdd) { enumRemapsWriter.WriteLine($"{remap}={enumName}"); remaps.TryAdd(remap, enumName); } } } if (this.suggestedEnumRenames.Count != 0) { this.output.Add("Suggested enum names:"); this.output.AddRange(this.suggestedEnumRenames); this.suggestedEnumRenames.Clear(); } }
private void WriteEnumsAndRemaps( Dictionary <string, string> remaps) { // Output the enums and the rsp entries that map parameters and fields to use // enum names var enumRemapsFileName = Path.Combine(repoRoot, $@"generation\emitter\generated\enumsRemap.rsp"); using StreamWriter enumRemapsWriter = new StreamWriter(enumRemapsFileName); enumRemapsWriter.WriteLine("--remap"); HashSet <string> manualEnumNames = GetManualEnumNames(); // For each enum object... foreach (var obj in enumObjectsFromJsons) { if (obj.name.StartsWith("CREDUIWIN")) { } // Skip if no members if (obj.members.Count == 0) { continue; } string foundNamespace = null; List <string> remapsToAdd = new List <string>(); // For each use in an enum... foreach (var use in obj.uses) { string lookupNameForNamespace; string remapName = use.ToString(); // lookupNameForNamespace = the name to use to lookup the namespace // remapName = used in .rsp to map a param or field to use the enum if (use.@interface != null) { lookupNameForNamespace = use.@interface; } else if (use.method != null) { lookupNameForNamespace = use.method; } else { lookupNameForNamespace = use.@struct; } // If we haven't found a namespace yet, try to look it up if (foundNamespace == null) { requiredNamespaces.TryGetValue(lookupNameForNamespace, out foundNamespace); } // If we don't already have a remap entry for this param or field, add one if (!remaps.ContainsKey(remapName)) { remapsToAdd.Add(remapName); } } if (foundNamespace == null) { foundNamespace = "Windows.Win32.SystemServices"; } bool existsAsManualEnum = manualEnumNames.TryGetValue(obj.name, out var objectForRemapName); bool addedEnum = false; var objectForRemap = obj; // This assumes that the manual version is more reliable. if (!existsAsManualEnum) { // If the enum doesn't have any remaps and isn't // an auto-poopulate, go to next object bool shouldWriteEnum = (remapsToAdd.Count != 0 || obj.autoPopulate != null); if (!shouldWriteEnum) { continue; } // Lookup the enum writer in the cache or add it if we can't find it if (!namespacesToEnumWriters.TryGetValue(foundNamespace, out var enumWriter)) { string fixedNamespaceName = foundNamespace.Replace("Windows.Win32.", string.Empty); string enumFile = Path.Combine(repoRoot, $@"generation\emitter\generated\{fixedNamespaceName}.enums.cs"); if (File.Exists(enumFile)) { File.Delete(enumFile); } enumWriter = new EnumWriter(enumFile, foundNamespace); namespacesToEnumWriters.Add(foundNamespace, enumWriter); } if (obj.autoPopulate == null) { foreach (var member in obj.members) { if (enumMemberNameToEnumObj.TryGetValue(member.name, out var list)) { objectForRemap = list.Where(e => e.autoPopulate != null).FirstOrDefault(); if (objectForRemap == null) { objectForRemap = list.Where(e => e.members.Any(m => m.value != null)).FirstOrDefault(); if (objectForRemap == null) { objectForRemap = obj; } } break; } } } if (obj == objectForRemap) { addedEnum = enumWriter.AddEnum(obj); } } else { } if (addedEnum || existsAsManualEnum || obj != objectForRemap) { foreach (var remap in remapsToAdd) { enumRemapsWriter.WriteLine($"{remap}={objectForRemap.name}"); remaps.TryAdd(remap, objectForRemap.name); } } } }