Ejemplo n.º 1
0
        public bool UpdateNameReference(ConfuserContext context, INameService service)
        {
            string name   = sig.ReflectionName;
            string prefix = xmlnsCtx.GetPrefix(sig.ReflectionNamespace, sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module.Assembly);

            if (!string.IsNullOrEmpty(prefix))
            {
                name = prefix + ":" + name;
            }

            if (propRec != null)
            {
                if (string.Equals(propRec.Value, name, StringComparison.Ordinal))
                {
                    return(false);
                }
                propRec.Value = name;
            }
            else
            {
                if (string.Equals(textRec.Value, name, StringComparison.Ordinal))
                {
                    return(false);
                }
                textRec.Value = name;
            }

            return(true);
        }
Ejemplo n.º 2
0
        private TypeSig ResolveType(string typeName, out string prefix)
        {
            List <Tuple <AssemblyDef, string> > clrNs;

            int index = typeName.IndexOf(':');

            if (index == -1)
            {
                prefix = "";
                if (!xmlns.TryGetValue(prefix, out clrNs))
                {
                    return(null);
                }
            }
            else
            {
                prefix = typeName.Substring(0, index);
                if (!xmlns.TryGetValue(prefix, out clrNs))
                {
                    return(null);
                }

                typeName = typeName.Substring(index + 1);
            }

            foreach (var ns in clrNs)
            {
                TypeSig sig = TypeNameParser.ParseAsTypeSigReflectionThrow(module, ns.Item2 + "." + typeName, new DummyAssemblyRefFinder(ns.Item1));
                if (sig.ToBasicTypeDefOrRef().ResolveTypeDef() != null)
                {
                    return(sig);
                }
            }
            return(null);
        }
Ejemplo n.º 3
0
        void AnalyzePropertyPath(string path)
        {
            var propertyPath = new PropertyPath(path);

            foreach (PropertyPathPart part in propertyPath.Parts)
            {
                if (part.IsAttachedDP())
                {
                    string type, property;
                    part.ExtractAttachedDP(out type, out property);
                    if (type != null)
                    {
                        string  prefix;
                        TypeSig sig = ResolveType(type, out prefix);
                        if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                        {
                            var reference = new BAMLPathTypeReference(xmlnsCtx, sig, part);
                            AddTypeSigReference(sig, reference);
                        }
                    }
                }
                else
                {
                    List <PropertyDef> candidates;
                    if (properties.TryGetValue(part.Name, out candidates))
                    {
                        foreach (PropertyDef property in candidates)
                        {
                            if (!parameters.GetParameter(context, property, "forceRen", false))
                            {
                                service.SetCanRename(property, false, "It is potentially used for XAML bindings");
                            }
                        }
                    }
                }

                if (part.IndexerArguments != null)
                {
                    foreach (PropertyPathIndexer indexer in part.IndexerArguments)
                    {
                        if (!string.IsNullOrEmpty(indexer.Type))
                        {
                            string  prefix;
                            TypeSig sig = ResolveType(indexer.Type, out prefix);
                            if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                            {
                                var reference = new BAMLPathTypeReference(xmlnsCtx, sig, part);
                                AddTypeSigReference(sig, reference);
                            }
                        }
                    }
                }
            }
        }
        public bool UpdateNameReference(DotProtectContext context, INameService service)
        {
            string typeName = sig.ReflectionName;
            string prefix   = xmlnsCtx.GetPrefix(sig.ReflectionNamespace, sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module.Assembly);

            if (!string.IsNullOrEmpty(prefix))
            {
                typeName = prefix + ":" + typeName;
            }
            rec.Value = typeName + "." + member.Name;
            return(true);
        }
Ejemplo n.º 5
0
        public bool UpdateNameReference(ConfuserContext context, INameService service)
        {
            string typeName = sig.ReflectionName;
            string prefix   = xmlnsCtx.GetPrefix(sig.ReflectionNamespace, sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module.Assembly);

            if (!string.IsNullOrEmpty(prefix))
            {
                typeName = prefix + ":" + typeName;
            }
            var newValue = typeName + "." + member.Name;

            if (string.Equals(rec.Value, newValue, StringComparison.Ordinal))
            {
                return(false);
            }
            rec.Value = newValue;
            return(true);
        }
Ejemplo n.º 6
0
        public bool UpdateNameReference(DotProtectContext context, INameService service)
        {
            string name   = sig.ReflectionName;
            string prefix = xmlnsCtx.GetPrefix(sig.ReflectionNamespace, sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module.Assembly);

            if (!string.IsNullOrEmpty(prefix))
            {
                name = prefix + ":" + name;
            }
            if (propRec != null)
            {
                propRec.Value = name;
            }
            else
            {
                textRec.Value = name;
            }
            return(true);
        }
        public bool UpdateNameReference(ConfuserContext context, INameService service)
        {
            string name   = sig.ReflectionName;
            string prefix = xmlnsCtx.GetPrefix(sig.ReflectionNamespace, sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module.Assembly);

            if (!string.IsNullOrEmpty(prefix))
            {
                name = prefix + ":" + name;
            }
            if (indexer != null)
            {
                indexer.Type = name;
            }
            else
            {
                attachedDP.ExtractAttachedDP(out string oldType, out string property);
                attachedDP.Name = string.Format("({0}.{1})", name, property);
            }
            return(true);
        }
Ejemplo n.º 8
0
        private void ProcessConverter(PropertyWithConverterRecord rec, TypeDef type)
        {
            TypeDef converter = ResolveType(rec.ConverterTypeId);

            if (converter.FullName == "System.ComponentModel.EnumConverter")
            {
                if (type != null && context.Modules.Contains((ModuleDefMD)type.Module))
                {
                    FieldDef enumField = type.FindField(rec.Value);
                    if (enumField != null)
                    {
                        service.AddReference(enumField, new BAMLEnumReference(enumField, rec));
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Input.CommandConverter")
            {
                string cmd   = rec.Value.Trim();
                int    index = cmd.IndexOf('.');
                if (index != -1)
                {
                    string  typeName = cmd.Substring(0, index);
                    string  prefix;
                    TypeSig sig = ResolveType(typeName, out prefix);
                    if (sig != null)
                    {
                        string cmdName = cmd.Substring(index + 1);

                        TypeDef typeDef = sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                        if (context.Modules.Contains((ModuleDefMD)typeDef.Module))
                        {
                            PropertyDef property = typeDef.FindProperty(cmdName);
                            if (property != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, property, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(property, RenameMode.Letters);
                                service.AddReference(property, reference);
                            }
                            FieldDef field = typeDef.FindField(cmdName);
                            if (field != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, field, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(field, RenameMode.Letters);
                                service.AddReference(field, reference);
                            }
                            if (property == null && field == null)
                            {
                                context.Logger.WarnFormat("Could not resolve command '{0}' in '{1}'.", cmd, bamlName);
                            }
                        }
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Markup.DependencyPropertyConverter")
            {
                // Umm... Again nothing to do, DP already won't be renamed.
            }
            else if (converter.FullName == "System.Windows.PropertyPathConverter")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (converter.FullName == "System.Windows.Markup.RoutedEventConverter")
            {
                ;
            }
            else if (converter.FullName == "System.Windows.Markup.TypeTypeConverter")
            {
                string  prefix;
                TypeSig sig = ResolveType(rec.Value.Trim(), out prefix);
                if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                {
                    var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, rec);
                    AddTypeSigReference(sig, reference);
                }
            }
        }
Ejemplo n.º 9
0
        private void ProcessElementHeader(BamlElement elem)
        {
            // Resolve type & properties of the element.
            switch (elem.Header.Type)
            {
            case BamlRecordType.ConstructorParametersStart:
                elem.Type      = elem.Parent.Type;
                elem.Attribute = elem.Parent.Attribute;
                break;

            case BamlRecordType.DocumentStart:
                break;

            case BamlRecordType.ElementStart:
            case BamlRecordType.NamedElementStart:
                elem.Type = ResolveType(((ElementStartRecord)elem.Header).TypeId);
                if (elem.Type.FullName == "System.Windows.Data.Binding")
                {
                    // Here comes the trouble...
                    // Aww, never mind...
                    foreach (BamlElement child in elem.Children)
                    {
                        if (child.Header.Type == BamlRecordType.ConstructorParametersStart)
                        {
                            var    cnt   = (TextRecord)child.Body[0];
                            string value = cnt.Value;
                            if (cnt is TextWithIdRecord)
                            {
                                value = strings[((TextWithIdRecord)cnt).ValueId].Value;
                            }
                            AnalyzePropertyPath(cnt.Value);
                        }
                    }
                }
                else if (elem.Type.FullName == "System.Windows.Markup.TypeExtension")
                {
                    foreach (BamlElement child in elem.Children)
                    {
                        if (child.Header.Type == BamlRecordType.ConstructorParametersStart)
                        {
                            var    cnt   = (TextRecord)child.Body[0];
                            string value = cnt.Value;
                            if (cnt is TextWithIdRecord)
                            {
                                value = strings[((TextWithIdRecord)cnt).ValueId].Value;
                            }

                            string  prefix;
                            TypeSig sig = ResolveType(value.Trim(), out prefix);
                            if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                            {
                                var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, cnt);
                                AddTypeSigReference(sig, reference);
                            }
                        }
                    }
                }
                elem.Attribute = elem.Parent.Attribute;
                if (elem.Attribute != null)
                {
                    elem.Type = GetAttributeType(elem.Attribute);
                }
                break;

            case BamlRecordType.PropertyArrayStart:
            case BamlRecordType.PropertyComplexStart:
            case BamlRecordType.PropertyDictionaryStart:
            case BamlRecordType.PropertyListStart:
                Tuple <IDnlibDef, TypeDef> attrInfo = ResolveAttribute(((PropertyComplexStartRecord)elem.Header).AttributeId);
                elem.Type      = attrInfo.Item2;
                elem.Attribute = attrInfo.Item1;
                if (elem.Attribute != null)
                {
                    elem.Type = GetAttributeType(elem.Attribute);
                }
                break;

            case BamlRecordType.KeyElementStart:
            case BamlRecordType.StaticResourceStart:
                // i.e. <x:Key></x:Key>
                elem.Type      = module.CorLibTypes.Object.TypeDefOrRef.ResolveTypeDef();
                elem.Attribute = null;
                break;
            }
        }
Ejemplo n.º 10
0
        void ProcessConverter(PropertyWithConverterRecord rec, TypeDef type)
        {
            TypeDef converter = ResolveType(rec.ConverterTypeId);

            if (converter.FullName == "System.ComponentModel.EnumConverter")
            {
                if (type != null && context.Modules.Contains((ModuleDefMD)type.Module))
                {
                    FieldDef enumField = type.FindField(rec.Value);
                    if (enumField != null)
                    {
                        service.AddReference(enumField, new BAMLEnumReference(enumField, rec));
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Input.CommandConverter")
            {
                string cmd   = rec.Value.Trim();
                int    index = cmd.IndexOf('.');
                if (index != -1)
                {
                    string  typeName = cmd.Substring(0, index);
                    string  prefix;
                    TypeSig sig = ResolveType(typeName, out prefix);
                    if (sig != null)
                    {
                        string cmdName = cmd.Substring(index + 1);

                        TypeDef typeDef = sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                        if (context.Modules.Contains((ModuleDefMD)typeDef.Module))
                        {
                            PropertyDef property = typeDef.FindProperty(cmdName);
                            if (property != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, property, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(property, RenameMode.Letters);
                                service.AddReference(property, reference);
                            }
                            FieldDef field = typeDef.FindField(cmdName);
                            if (field != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, field, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(field, RenameMode.Letters);
                                service.AddReference(field, reference);
                            }
                            if (property == null && field == null)
                            {
                                context.Logger.LogFormat("WARN: Could not resolve command '{0}' in '{1}'.", cmd, CurrentBAMLName);
                            }
                        }
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Markup.DependencyPropertyConverter")
            {
                // Umm... Again nothing to do, DP already won't be renamed.
            }
            else if (converter.FullName == "System.Windows.PropertyPathConverter")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (converter.FullName == "System.Windows.Markup.RoutedEventConverter")
            {
                ;
            }
            else if (converter.FullName == "System.Windows.Markup.TypeTypeConverter")
            {
                string  prefix;
                TypeSig sig = ResolveType(rec.Value.Trim(), out prefix);
                if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                {
                    var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, rec);
                    AddTypeSigReference(sig, reference);
                }
            }

            var    attrInfo = ResolveAttribute(rec.AttributeId);
            string attrName = null;

            if (attrInfo.Item1 != null)
            {
                attrName = attrInfo.Item1.Name;
            }
            else if (attrInfo.Item2 != null)
            {
                attrName = attrInfo.Item2.Name;
            }

            if (attrName == "DisplayMemberPath")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (attrName == "Source")
            {
                string declType = null;
                if (attrInfo.Item1 is IMemberDef)
                {
                    declType = ((IMemberDef)attrInfo.Item1).DeclaringType.FullName;
                }
                else if (attrInfo.Item2 != null)
                {
                    declType = ResolveType(attrInfo.Item2.OwnerTypeId).FullName;
                }
                if (declType == "System.Windows.ResourceDictionary")
                {
                    var src = rec.Value.ToUpperInvariant();
                    if (src.EndsWith(".BAML") || src.EndsWith(".XAML"))
                    {
                        var match = WPFAnalyzer.UriPattern.Match(src);
                        if (match.Success)
                        {
                            src = match.Groups[1].Value;
                        }
                        else if (rec.Value.Contains("/"))
                        {
                            context.Logger.LogFormat("WARN: Fail to extract XAML name from '{0}'.", rec.Value);
                        }

                        if (!src.Contains("//"))
                        {
                            var rel = new Uri(new Uri(packScheme + "application:,,,/" + CurrentBAMLName), src);
                            src = rel.LocalPath;
                        }
                        var reference = new BAMLPropertyReference(rec);
                        src = src.TrimStart('/');
                        var baml     = src.Substring(0, src.Length - 5) + ".BAML";
                        var xaml     = src.Substring(0, src.Length - 5) + ".XAML";
                        var bamlRefs = service.FindRenamer <WPFAnalyzer>().bamlRefs;
                        bamlRefs.AddListEntry(baml, reference);
                        bamlRefs.AddListEntry(xaml, reference);
                        bamlRefs.AddListEntry(Uri.EscapeUriString(baml), reference);
                        bamlRefs.AddListEntry(Uri.EscapeUriString(xaml), reference);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        void ProcessElementBody(BamlElement root, BamlElement elem)
        {
            foreach (BamlRecord rec in elem.Body)
            {
                // Resolve the type & property for simple property record too.
                TypeDef   type = null;
                IDnlibDef attr = null;
                if (rec is PropertyRecord)
                {
                    var propRec  = (PropertyRecord)rec;
                    var attrInfo = ResolveAttribute(propRec.AttributeId);
                    type = attrInfo.Item3;
                    attr = attrInfo.Item1;
                    if (attr != null)
                    {
                        type = GetAttributeType(attr);
                    }

                    if (attrInfo.Item1 is EventDef)
                    {
                        MethodDef method = root.Type.FindMethod(propRec.Value);
                        if (method == null)
                        {
                            context.Logger.LogFormat("WARN: Cannot resolve method '{0}' in '{1}'.", root.Type.FullName, propRec.Value);
                        }
                        else
                        {
                            var reference = new BAMLAttributeReference(method, propRec);
                            service.AddReference(method, reference);
                        }
                    }

                    if (rec is PropertyWithConverterRecord)
                    {
                        ProcessConverter((PropertyWithConverterRecord)rec, type);
                    }
                }
                else if (rec is PropertyComplexStartRecord)
                {
                    var attrInfo = ResolveAttribute(((PropertyComplexStartRecord)rec).AttributeId);
                    type = attrInfo.Item3;
                    attr = attrInfo.Item1;
                    if (attr != null)
                    {
                        type = GetAttributeType(attr);
                    }
                }
                else if (rec is ContentPropertyRecord)
                {
                    var attrInfo = ResolveAttribute(((ContentPropertyRecord)rec).AttributeId);
                    type = attrInfo.Item3;
                    attr = attrInfo.Item1;
                    if (elem.Attribute != null && attr != null)
                    {
                        type = GetAttributeType(attr);
                    }
                    foreach (BamlElement child in elem.Children)
                    {
                        child.Type      = type;
                        child.Attribute = attr;
                    }
                }
                else if (rec is PropertyCustomRecord)
                {
                    var customRec = (PropertyCustomRecord)rec;
                    var attrInfo  = ResolveAttribute(customRec.AttributeId);
                    type = attrInfo.Item3;
                    attr = attrInfo.Item1;
                    if (elem.Attribute != null && attr != null)
                    {
                        type = GetAttributeType(attr);
                    }

                    if ((customRec.SerializerTypeId & ~0x4000) != 0 && (customRec.SerializerTypeId & ~0x4000) == 0x89)
                    {
                        // See BamlRecordReader.GetCustomDependencyPropertyValue.
                        // Umm... Well, actually nothing to do, since this record only describe DP, which already won't be renamed.
                    }
                }
                else if (rec is PropertyWithExtensionRecord)
                {
                    var extRec   = (PropertyWithExtensionRecord)rec;
                    var attrInfo = ResolveAttribute(extRec.AttributeId);
                    type = attrInfo.Item3;
                    attr = attrInfo.Item1;
                    if (elem.Attribute != null && attr != null)
                    {
                        type = GetAttributeType(attr);
                    }

                    if (extRec.Flags == 602)
                    {
                        // Static Extension
                        // We only care about the references in user-defined assemblies, so skip built-in attributes
                        // Also, ValueId is a resource ID, which is not implemented, so just skip it.
                        if ((short)extRec.ValueId >= 0)
                        {
                            attrInfo = ResolveAttribute(extRec.ValueId);

                            var attrTarget = attrInfo.Item1;
                            if (attrTarget == null)
                            {
                                TypeSig declType;
                                TypeDef declTypeDef;
                                if (typeRefs.TryGetValue(attrInfo.Item2.OwnerTypeId, out declType))
                                {
                                    declTypeDef = declType.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                                }
                                else
                                {
                                    Debug.Assert((short)attrInfo.Item2.OwnerTypeId < 0);
                                    declTypeDef = things.Types((KnownTypes)(-(short)attrInfo.Item2.OwnerTypeId));
                                }
                                attrTarget = declTypeDef.FindField(attrInfo.Item2.Name);
                            }

                            if (attrTarget != null)
                            {
                                service.AddReference(attrTarget, new BAMLAttributeReference(attrTarget, attrInfo.Item2));
                            }
                        }
                    }
                }
                else if (rec is TextRecord)
                {
                    var    txt   = (TextRecord)rec;
                    string value = txt.Value;
                    if (txt is TextWithIdRecord)
                    {
                        value = strings[((TextWithIdRecord)txt).ValueId].Value;
                    }

                    string  prefix;
                    TypeSig sig = ResolveType(value.Trim(), out prefix);
                    if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                    {
                        var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, txt);
                        AddTypeSigReference(sig, reference);
                    }
                    else
                    {
                        AnalyzePropertyPath(value);
                    }
                }
            }
        }
Ejemplo n.º 12
0
        void ProcessConverter(PropertyWithConverterRecord rec, TypeDef type)
        {
            TypeDef converter = ResolveType(rec.ConverterTypeId);

            if (converter.FullName == "System.ComponentModel.EnumConverter")
            {
                if (type != null && context.Modules.Contains((ModuleDefMD)type.Module))
                {
                    FieldDef enumField = type.FindField(rec.Value);
                    if (enumField != null)
                    {
                        service.AddReference(enumField, new BAMLEnumReference(enumField, rec));
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Input.CommandConverter")
            {
                string cmd   = rec.Value.Trim();
                int    index = cmd.IndexOf('.');
                if (index != -1)
                {
                    string  typeName = cmd.Substring(0, index);
                    string  prefix;
                    TypeSig sig = ResolveType(typeName, out prefix);
                    if (sig != null)
                    {
                        string cmdName = cmd.Substring(index + 1);

                        TypeDef typeDef = sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                        if (context.Modules.Contains((ModuleDefMD)typeDef.Module))
                        {
                            PropertyDef property = typeDef.FindProperty(cmdName);
                            if (property != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, property, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(property, RenameMode.Letters);
                                service.AddReference(property, reference);
                            }
                            FieldDef field = typeDef.FindField(cmdName);
                            if (field != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, field, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(field, RenameMode.Letters);
                                service.AddReference(field, reference);
                            }
                            if (property == null && field == null)
                            {
                                context.Logger.WarnFormat("Could not resolve command '{0}' in '{1}'.", cmd, CurrentBAMLName);
                            }
                        }
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Markup.DependencyPropertyConverter")
            {
                // Umm... Again nothing to do, DP already won't be renamed.
            }
            else if (converter.FullName == "System.Windows.PropertyPathConverter")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (converter.FullName == "System.Windows.Markup.RoutedEventConverter")
            {
                ;
            }
            else if (converter.FullName == "System.Windows.Markup.TypeTypeConverter")
            {
                string  prefix;
                TypeSig sig = ResolveType(rec.Value.Trim(), out prefix);
                if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                {
                    var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, rec);
                    AddTypeSigReference(sig, reference);
                }
            }

            var    attrInfo = ResolveAttribute(rec.AttributeId);
            string attrName = null;

            if (attrInfo.Item1 != null)
            {
                attrName = attrInfo.Item1.Name;
            }
            else if (attrInfo.Item2 != null)
            {
                attrName = attrInfo.Item2.Name;
            }

            if (attrName == "DisplayMemberPath")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (attrName == "Source")
            {
                string declType = null;
                if (attrInfo.Item1 is IMemberDef)
                {
                    declType = ((IMemberDef)attrInfo.Item1).DeclaringType.FullName;
                }
                else if (attrInfo.Item2 != null)
                {
                    declType = ResolveType(attrInfo.Item2.OwnerTypeId).FullName;
                }
                if (declType == "System.Windows.ResourceDictionary")
                {
                    var src = rec.Value.ToUpperInvariant();
                    if (src.EndsWith(".BAML") || src.EndsWith(".XAML"))
                    {
                        var refModule = Module;
                        var match     = WPFAnalyzer.UriPattern.Match(src);
                        if (match.Success)
                        {
                            var resourceAssemblyName = match.Groups[1].Success ? match.Groups[1].Value : string.Empty;
                            // Check if the expression contains a resource name (group 1)
                            // If it does, check if it is this assembly.
                            if (!string.IsNullOrWhiteSpace(resourceAssemblyName) &&
                                !resourceAssemblyName.Equals(Module.Assembly.Name.String, StringComparison.OrdinalIgnoreCase))
                            {
                                // Let's see if we can find this assembly.
                                refModule = context.Modules.FirstOrDefault(m =>
                                                                           resourceAssemblyName.Equals(m.Assembly.Name.String,
                                                                                                       StringComparison.OrdinalIgnoreCase));

                                if (refModule == null)
                                {
                                    // This resource points to an assembly that is not part of the obfuscation.
                                    // Leave it alone!
                                    return;
                                }
                            }
                            src = match.Groups[2].Value;
                        }
                        else if (rec.Value.Contains("/"))
                        {
                            context.Logger.WarnFormat("Fail to extract XAML name from '{0}'.", rec.Value);
                        }

                        if (!src.StartsWith(packScheme, StringComparison.OrdinalIgnoreCase))
                        {
                            var rel = new Uri(new Uri(packScheme + "application:,,,/" + CurrentBAMLName), src);
                            src = rel.LocalPath;
                        }
                        var reference = new BAMLPropertyReference(refModule, rec);
                        src = WebUtility.UrlDecode(src.TrimStart('/'));
                        var baml     = src.Substring(0, src.Length - 5) + ".BAML";
                        var xaml     = src.Substring(0, src.Length - 5) + ".XAML";
                        var bamlRefs = service.FindRenamer <WPFAnalyzer>().bamlRefs;
                        bamlRefs.AddListEntry(baml, reference);
                        bamlRefs.AddListEntry(xaml, reference);
                    }
                }
            }
        }