Esempio n. 1
0
        public BamlDocument Analyze(ModuleDefMD module, string bamlName, byte[] data)
        {
            this.module   = module;
            this.bamlName = bamlName;
            if (module.IsClr40)
            {
                things = thingsv4 ?? (thingsv4 = new KnownThingsv4(context, module));
            }
            else
            {
                things = thingsv3 ?? (thingsv3 = new KnownThingsv3(context, module));
            }

            Debug.Assert(BitConverter.ToInt32(data, 0) == data.Length - 4);

            BamlDocument document = BamlReader.ReadDocument(new MemoryStream(data, 4, data.Length - 4));

            // Remove debug infos
            document.RemoveWhere(rec => rec is LineNumberAndPositionRecord || rec is LinePositionRecord);

            // Populate references
            PopulateReferences(document);

            // Process elements
            BamlElement rootElem = BamlElement.Read(document);
            BamlElement trueRoot = rootElem.Children.Single();
            var         stack    = new Stack <BamlElement>();

            stack.Push(rootElem);
            while (stack.Count > 0)
            {
                BamlElement elem = stack.Pop();
                ProcessBAMLElement(trueRoot, elem);
                foreach (BamlElement child in elem.Children)
                {
                    stack.Push(child);
                }
            }

            return(document);
        }
Esempio n. 2
0
        public static BamlElement Read(BamlDocument document)
        {
            Debug.Assert(document.Count > 0 && document[0].Type == BamlRecordType.DocumentStart);

            BamlElement current = null;
            var stack = new Stack<BamlElement>();

            for (int i = 0; i < document.Count; i++) {
                if (IsHeader(document[i])) {
                    BamlElement prev = current;

                    current = new BamlElement();
                    current.Header = document[i];
                    current.Body = new List<BamlRecord>();
                    current.Children = new List<BamlElement>();

                    if (prev != null) {
                        prev.Children.Add(current);
                        current.Parent = prev;
                        stack.Push(prev);
                    }
                }
                else if (IsFooter(document[i])) {
                    if (current == null)
                        throw new Exception("Unexpected footer.");

                    while (!IsMatch(current.Header, document[i])) {
                        // End record can be omited (sometimes).
                        if (stack.Count > 0)
                            current = stack.Pop();
                    }
                    current.Footer = document[i];
                    if (stack.Count > 0)
                        current = stack.Pop();
                }
                else
                    current.Body.Add(document[i]);
            }
            Debug.Assert(stack.Count == 0);
            return current;
        }
Esempio n. 3
0
		void AnalyzeBAMLElement(BAMLAnalyzer analyzer, BamlElement elem) {
			foreach (var rec in elem.Body) {
				var prop = rec as PropertyWithConverterRecord;
				if (prop == null)
					continue;

				var attr = analyzer.ResolveAttribute(prop.AttributeId);
				string attrName = null;
				if (attr.Item2 != null)
					attrName = attr.Item2.Name;
				else if (attr.Item1 != null)
					attrName = attr.Item1.Name;

				if (attrName == "Attach")
					AnalyzeMessageAttach(analyzer, attr, prop.Value);

				if (attrName == "Name")
					AnalyzeAutoBind(analyzer, attr, prop.Value);

				if (attrName == "MethodName")
					AnalyzeActionMessage(analyzer, attr, prop.Value);
			}
		}
Esempio n. 4
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:
                    // i.e. <x:Key></x:Key>
                    elem.Type = module.CorLibTypes.Object.TypeDefOrRef.ResolveTypeDef();
                    elem.Attribute = null;
                    break;

                case BamlRecordType.StaticResourceStart:
                    throw new NotSupportedException();
            }
        }
Esempio n. 5
0
        private 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;
                    Tuple<IDnlibDef, TypeDef> attrInfo = ResolveAttribute(propRec.AttributeId);
                    type = attrInfo.Item2;
                    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.WarnFormat("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) {
                    Tuple<IDnlibDef, TypeDef> attrInfo = ResolveAttribute(((PropertyComplexStartRecord)rec).AttributeId);
                    type = attrInfo.Item2;
                    attr = attrInfo.Item1;
                    if (attr != null)
                        type = GetAttributeType(attr);
                }
                else if (rec is ContentPropertyRecord) {
                    Tuple<IDnlibDef, TypeDef> attrInfo = ResolveAttribute(((ContentPropertyRecord)rec).AttributeId);
                    type = attrInfo.Item2;
                    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;
                    Tuple<IDnlibDef, TypeDef> attrInfo = ResolveAttribute(customRec.AttributeId);
                    type = attrInfo.Item2;
                    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;
                    Tuple<IDnlibDef, TypeDef> attrInfo = ResolveAttribute(extRec.AttributeId);
                    type = attrInfo.Item2;
                    attr = attrInfo.Item1;
                    if (elem.Attribute != null && attr != null)
                        type = GetAttributeType(attr);

                    // Umm... Nothing to do here too, since the value only contains either typeId/memberId, which already have references attached.
                }
            }
        }
Esempio n. 6
0
 private void ProcessBAMLElement(BamlElement root, BamlElement elem)
 {
     ProcessElementHeader(elem);
     ProcessElementBody(root, elem);
 }
Esempio n. 7
0
        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);
                    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:
                    var attrInfo = ResolveAttribute(((PropertyComplexStartRecord)elem.Header).AttributeId);
                    elem.Type = attrInfo.Item3;
                    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;
            }
        }
Esempio n. 8
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.WarnFormat("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);
                }
            }
        }
Esempio n. 9
0
        void ProcessBAMLElement(BamlElement root, BamlElement elem)
        {
            ProcessElementHeader(elem);
            ProcessElementBody(root, elem);

            if (AnalyzeElement != null)
                AnalyzeElement(this, elem);
        }
Esempio n. 10
0
        private 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;
                    Tuple <IDnlibDef, TypeDef> attrInfo = ResolveAttribute(propRec.AttributeId);
                    type = attrInfo.Item2;
                    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.WarnFormat("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)
                {
                    Tuple <IDnlibDef, TypeDef> attrInfo = ResolveAttribute(((PropertyComplexStartRecord)rec).AttributeId);
                    type = attrInfo.Item2;
                    attr = attrInfo.Item1;
                    if (attr != null)
                    {
                        type = GetAttributeType(attr);
                    }
                }
                else if (rec is ContentPropertyRecord)
                {
                    Tuple <IDnlibDef, TypeDef> attrInfo = ResolveAttribute(((ContentPropertyRecord)rec).AttributeId);
                    type = attrInfo.Item2;
                    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;
                    Tuple <IDnlibDef, TypeDef> attrInfo = ResolveAttribute(customRec.AttributeId);
                    type = attrInfo.Item2;
                    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;
                    Tuple <IDnlibDef, TypeDef> attrInfo = ResolveAttribute(extRec.AttributeId);
                    type = attrInfo.Item2;
                    attr = attrInfo.Item1;
                    if (elem.Attribute != null && attr != null)
                    {
                        type = GetAttributeType(attr);
                    }

                    // Umm... Nothing to do here too, since the value only contains either typeId/memberId, which already have references attached.
                }
            }
        }
Esempio n. 11
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;
            }
        }
Esempio n. 12
0
 private void ProcessBAMLElement(BamlElement root, BamlElement elem)
 {
     ProcessElementHeader(elem);
     ProcessElementBody(root, elem);
 }
Esempio n. 13
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);
                    }
                }
            }
        }
Esempio n. 14
0
        private 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.WarnFormat("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
                    {
                        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));
                        }
                    }
                }
            }
        }