private void AddUsedBaml(ResourcePart resourcePart) { if (usedBamlsCache.Contains(resourcePart)) { return; } Log($"BAML used: {resourcePart.Name}"); bamlsToScan.Enqueue(resourcePart); usedBamlsCache.Add(resourcePart); }
private void ScanWpfRoot() { foreach (Resource resource in definition.MainModule.Resources) { if (resource.Name == wpfRootResourceName) { wpfRootResource = resource as EmbeddedResource; } if (wpfRootResource != null) { break; } } if (wpfRootResource == null) { return; } Log($"Found WPF root resource: {wpfRootResourceName}"); wpfRootParts = new Dictionary <string, ResourcePart>(); using (Stream stream = wpfRootResource.GetResourceStream()) { using (ResourceReader reader = new ResourceReader(stream)) foreach (DictionaryEntry entry in reader) { ResourcePart part = new ResourcePart(entry); if (part.TypeName != null) { TypeDefinition type; if (typesMap.TryGetValue(part.TypeName, out type)) { part.TypeDef = type; bamlMap.Add(type, part); } } wpfRootParts.Add(part.Name, part); } } }
private void WalkBaml(ResourcePart part) { Dictionary <string, string> namespaces = new Dictionary <string, string>(); foreach (BamlRecord record in part.Baml) { if (record.Type == BamlRecordType.TypeInfo) { TypeInfoRecord typeInfo = (TypeInfoRecord)record; TypeDefinition type; if (typesMap.TryGetValue(typeInfo.TypeFullName, out type)) { AddUsedType(type); } continue; } if (record.Type == BamlRecordType.XmlnsProperty) { XmlnsPropertyRecord ns = (XmlnsPropertyRecord)record; const string CLR_NAMESPACE = "clr-namespace:"; if (ns.XmlNamespace.StartsWith(CLR_NAMESPACE)) { namespaces.Add(ns.Prefix, ns.XmlNamespace.Substring(CLR_NAMESPACE.Length)); } continue; } if (record.Type == BamlRecordType.Text) { TextRecord textRecord = (TextRecord)record; int index = textRecord.Value.IndexOf(':'); if (index == -1) { continue; // not ns reference } string name; if (!namespaces.TryGetValue(textRecord.Value.Substring(0, index), out name)) { continue; } name += "." + textRecord.Value.Substring(index + 1); TypeDefinition type; // type as string? if (typesMap.TryGetValue(name, out type)) { AddUsedType(type); continue; } index = name.LastIndexOf(".", StringComparison.InvariantCulture); // member? if (typesMap.TryGetValue(name.Substring(0, index), out type)) { AddUsedType(type); } continue; } if (record.Type == BamlRecordType.PropertyWithConverter) { PropertyWithConverterRecord propertyInfo = (PropertyWithConverterRecord)record; string resourceName = propertyInfo.Value; if (resourceName.StartsWith(wpfPathPrefix)) { resourceName = resourceName.Substring(wpfPathPrefix.Length, resourceName.Length - wpfPathPrefix.Length); } if (resourceName.EndsWith(".xaml", StringComparison.InvariantCultureIgnoreCase)) { resourceName = resourceName.Substring(0, resourceName.Length - 4) + "baml"; } resourceName = resourceName.ToLower(); ResourcePart resourcePart; if (!wpfRootParts.TryGetValue(resourceName, out resourcePart)) { continue; } if (resourcePart.Baml != null) { AddUsedBaml(resourcePart); } else { Log($"WPF resource used: {resourceName}"); usedWpfResources.Add(resourceName); } } } }