// Token: 0x06001EC5 RID: 7877 RVA: 0x00093A70 File Offset: 0x00091C70 internal BamlRecord ReadNextRecord(BinaryReader bamlBinaryReader, long bytesAvailable, BamlRecordType recordType) { BamlRecord bamlRecord; switch (recordType) { case BamlRecordType.AssemblyInfo: bamlRecord = new BamlAssemblyInfoRecord(); goto IL_A6; case BamlRecordType.TypeInfo: bamlRecord = new BamlTypeInfoRecord(); goto IL_A6; case BamlRecordType.TypeSerializerInfo: bamlRecord = new BamlTypeInfoWithSerializerRecord(); goto IL_A6; case BamlRecordType.AttributeInfo: bamlRecord = new BamlAttributeInfoRecord(); goto IL_A6; case BamlRecordType.StringInfo: bamlRecord = new BamlStringInfoRecord(); goto IL_A6; case BamlRecordType.DefAttributeKeyString: bamlRecord = new BamlDefAttributeKeyStringRecord(); goto IL_A6; case BamlRecordType.DefAttributeKeyType: bamlRecord = new BamlDefAttributeKeyTypeRecord(); goto IL_A6; case BamlRecordType.KeyElementStart: bamlRecord = new BamlKeyElementStartRecord(); goto IL_A6; } bamlRecord = this._readCache[(int)recordType]; if (bamlRecord == null || bamlRecord.IsPinned) { bamlRecord = (this._readCache[(int)recordType] = this.AllocateRecord(recordType)); } IL_A6: bamlRecord.Next = null; if (bamlRecord != null) { if (bamlRecord.LoadRecordSize(bamlBinaryReader, bytesAvailable) && bytesAvailable >= (long)bamlRecord.RecordSize) { bamlRecord.LoadRecordData(bamlBinaryReader); } else { bamlRecord = null; } } return(bamlRecord); }
// Token: 0x0600208D RID: 8333 RVA: 0x00096540 File Offset: 0x00094740 internal override void Copy(BamlRecord record) { base.Copy(record); BamlAttributeInfoRecord bamlAttributeInfoRecord = (BamlAttributeInfoRecord)record; bamlAttributeInfoRecord._ownerId = this._ownerId; bamlAttributeInfoRecord._attributeId = this._attributeId; bamlAttributeInfoRecord._name = this._name; bamlAttributeInfoRecord._ownerType = this._ownerType; bamlAttributeInfoRecord._Event = this._Event; bamlAttributeInfoRecord._dp = this._dp; bamlAttributeInfoRecord._ei = this._ei; bamlAttributeInfoRecord._pi = this._pi; bamlAttributeInfoRecord._smi = this._smi; bamlAttributeInfoRecord._gmi = this._gmi; bamlAttributeInfoRecord._dpOrMiOrPi = this._dpOrMiOrPi; }
// Return the RoutedEvent given an attribute info record. The RoutedEvent // is cached in the info record. internal RoutedEvent GetRoutedEvent(BamlAttributeInfoRecord bamlAttributeInfoRecord) { if (null == bamlAttributeInfoRecord.Event) { Type ownerType = GetAttributeOwnerType(bamlAttributeInfoRecord); if (null != ownerType) { bamlAttributeInfoRecord.Event = XamlTypeMapper.RoutedEventFromName(bamlAttributeInfoRecord.Name,ownerType); } } return bamlAttributeInfoRecord.Event; }
// Return the DependencyProperty given an attribute info record. The DP // is cached in the info record. internal DependencyProperty GetDependencyProperty(BamlAttributeInfoRecord bamlAttributeInfoRecord) { if ((null == bamlAttributeInfoRecord.DP) && (null == bamlAttributeInfoRecord.PropInfo)) { // This will update the record GetAttributeOwnerType(bamlAttributeInfoRecord); if (null != bamlAttributeInfoRecord.OwnerType) { bamlAttributeInfoRecord.DP = DependencyProperty.FromName( bamlAttributeInfoRecord.Name, bamlAttributeInfoRecord.OwnerType); } } return bamlAttributeInfoRecord.DP; }
// Return the attribute owner Type given an attribute info record. // The owner Type is cached in the info record. private Type GetAttributeOwnerType(BamlAttributeInfoRecord bamlAttributeInfoRecord) { if (bamlAttributeInfoRecord.OwnerType == null) { if (bamlAttributeInfoRecord.OwnerTypeId < 0) { bamlAttributeInfoRecord.OwnerType = GetKnownTypeFromId(bamlAttributeInfoRecord.OwnerTypeId); } else { BamlTypeInfoRecord typeInfo = (BamlTypeInfoRecord)TypeIdMap[bamlAttributeInfoRecord.OwnerTypeId]; if (null != typeInfo) { bamlAttributeInfoRecord.OwnerType = GetTypeFromTypeInfo(typeInfo); } } } return bamlAttributeInfoRecord.OwnerType; }
// Return attribute info record given an ID. internal BamlAttributeInfoRecord GetAttributeInfoFromId(short id) { if (id < 0) { KnownProperties knownId = (KnownProperties)(-id); BamlAttributeInfoRecord record = new BamlAttributeInfoRecord(); record.AttributeId = id; record.OwnerTypeId = (short)-(short)KnownTypes.GetKnownElementFromKnownCommonProperty(knownId); GetAttributeOwnerType(record); // This will update the OwnerType property record.Name = GetAttributeNameFromKnownId(knownId); if(knownId < KnownProperties.MaxDependencyProperty) { DependencyProperty dp = KnownTypes.GetKnownDependencyPropertyFromId(knownId); record.DP = dp; } else { Type ownerType = record.OwnerType; record.PropInfo = ownerType.GetProperty(record.Name, BindingFlags.Instance | BindingFlags.Public); } return record; } return (BamlAttributeInfoRecord)AttributeIdMap[id]; }
// Add an already-loaded type info record to the map table. This is generally // appended as the baml file is being built. If we are loading an attribute // into an already set up map table, just ensure that we don't try to overwrite // an existing record something different. internal void LoadAttributeInfoRecord(BamlAttributeInfoRecord record) { Debug.Assert(AttributeIdMap.Count == record.AttributeId || record.Name == ((BamlAttributeInfoRecord)AttributeIdMap[record.AttributeId]).Name); if (AttributeIdMap.Count == record.AttributeId) { AttributeIdMap.Add(record); } }
internal short AddAttributeInfoMap( BinaryWriter binaryWriter, string assemblyFullName, // Name of assembly for owning or declaring type string typeFullName, // Type name of object that owns or declares this attribute Type owningType, // Actual type of the object the owns or declares this attribute string fieldName, // Name of the attribute Type attributeType, // Type of the attribute or property itself; not its owner type BamlAttributeUsage attributeUsage, // Special flags for how this attribute is used. out BamlAttributeInfoRecord bamlAttributeInfoRecord) // Record if not a known DP { short typeId; // If we do not already have a type record for the type associated with // this attribute, then recurse and write out the TypeInfo first. if (!GetTypeInfoId(binaryWriter, assemblyFullName, typeFullName, out typeId)) { // Get id for Type that owns or has this attribute declared on it. This is // refered to in the attribute info record and is also part of the key for // seeing if we already have an attribute info record for this attribute. Type serializerType = XamlTypeMapper.GetXamlSerializerForType(owningType); string serializerTypeAssemblyName = serializerType == null ? string.Empty : serializerType.Assembly.FullName; string serializerTypeName = serializerType == null ? string.Empty : serializerType.FullName; typeId = AddTypeInfoMap(binaryWriter, assemblyFullName, typeFullName, owningType, serializerTypeAssemblyName, serializerTypeName); } else if (typeId < 0) { // Only known types will have known properties short attributeId = (short)-KnownTypes.GetKnownPropertyAttributeId((KnownElements)(-typeId), fieldName); if (attributeId < 0) { // The property is known and doesn't need a record created. bamlAttributeInfoRecord = null; return attributeId; } } object key = GetAttributeInfoKey(typeFullName, fieldName); bamlAttributeInfoRecord = (BamlAttributeInfoRecord)GetHashTableData(key); if (null == bamlAttributeInfoRecord) { // The property is new and needs a record created. bamlAttributeInfoRecord = new BamlAttributeInfoRecord(); bamlAttributeInfoRecord.Name = fieldName; bamlAttributeInfoRecord.OwnerTypeId = typeId; bamlAttributeInfoRecord.AttributeId = (short)AttributeIdMap.Add(bamlAttributeInfoRecord); bamlAttributeInfoRecord.AttributeUsage = attributeUsage; // add to the hash ObjectHashTable.Add(key, bamlAttributeInfoRecord); // Write to BAML bamlAttributeInfoRecord.Write(binaryWriter); } return bamlAttributeInfoRecord.AttributeId; }
internal void UpdateAttachedPropertySetter(BamlAttributeInfoRecord attributeInfo) { if (attributeInfo.AttachedPropertySetter == null) { UpdateAttachedPropertyMethdodInfo(attributeInfo, true); } }
private void UpdateAttachedPropertyMethdodInfo(BamlAttributeInfoRecord attributeInfo, bool isSetter) { MethodInfo attachedPropertyInfo = null; Type propertyOwnerType = attributeInfo.OwnerType; Debug.Assert(propertyOwnerType != null); bool tryInternal = !ReflectionHelper.IsPublicType(propertyOwnerType); string propName = (isSetter ? "Set" : "Get") + attributeInfo.Name; BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy; // Check Set\GetFoo method presence try { if (!tryInternal) { // first try public methods attachedPropertyInfo = propertyOwnerType.GetMethod(propName, flags); } if (attachedPropertyInfo == null) { // if public method not found, try non-public method next. attachedPropertyInfo = propertyOwnerType.GetMethod(propName, flags | BindingFlags.NonPublic); } } catch (AmbiguousMatchException) { } int paramCount = isSetter ? 2 : 1; if (attachedPropertyInfo != null && attachedPropertyInfo.GetParameters().Length == paramCount) { // the MethodInfo has to be public or internal. Debug.Assert(attachedPropertyInfo.IsPublic || attachedPropertyInfo.IsAssembly || attachedPropertyInfo.IsFamilyOrAssembly); if (isSetter) { attributeInfo.AttachedPropertySetter = attachedPropertyInfo; } else { attributeInfo.AttachedPropertyGetter = attachedPropertyInfo; } } }
/// <summary> /// Helper function for getting Clr PropertyInfo on a type and updating the /// passed attribute info record. Also update the property cache with this /// attribute information if it was not already present. /// </summary> /// <remarks> /// Note that the ObjectHashTable may contain /// a BamlAttributeInfoRecord from a previous parse for the same property. If /// we find one in the hash table, use its property info instead of reflecting. /// </remarks> internal void UpdateClrPropertyInfo( Type currentParentType, BamlAttributeInfoRecord attribInfo) { Debug.Assert(null != attribInfo, "null attribInfo"); Debug.Assert(null != currentParentType, "null currentParentType"); bool isInternal = false; string propName = attribInfo.Name; BamlAttributeInfoRecord cachedInfoRecord; attribInfo.PropInfo = GetCachedMemberInfo(currentParentType, propName, true, out cachedInfoRecord) as PropertyInfo; if (attribInfo.PropInfo == null) { // If no cached property info, use the slow route of reflecting to get // the property info. attribInfo.PropInfo = PropertyInfoFromName(propName, currentParentType, !ReflectionHelper.IsPublicType(currentParentType), false, out isInternal); attribInfo.IsInternal = isInternal; if (attribInfo.PropInfo != null) { // If we successfully find a property info via reflection, cache it. if (cachedInfoRecord != null) { cachedInfoRecord.SetPropertyMember(attribInfo.PropInfo); cachedInfoRecord.IsInternal = attribInfo.IsInternal; } else { AddCachedAttributeInfo(currentParentType, attribInfo); } } } else { attribInfo.IsInternal = cachedInfoRecord.IsInternal; } }
/// <summary> /// Add cached member info for the property name. /// </summary> private void AddCachedAttributeInfo( Type ownerType, BamlAttributeInfoRecord infoRecord) { if (MapTable != null) { object key = MapTable.GetAttributeInfoKey(ownerType.FullName, infoRecord.Name); MapTable.AddHashTableData(key, infoRecord); } }
/// <summary> /// Get cached member info for the property name. This can be /// a PropertyInfo for the property or a MethodInfo for the static /// setter. This does not work for EventInfo, so don't call it. /// </summary> /// <param name="owner">Type of the owner of the property </param> /// <param name="propName">Name of the property</param> /// <param name="onlyPropInfo">True if the caller wants the PropertyInfo for the /// case where both a MethodInfo and propertyInfo are cached for this property /// </param> /// <param name="infoRecord">The attribute info record retrieved from /// the map table, if one is found. </param> /// <remarks> /// There is only one scenario under which two memberInfo need to be /// cached for a given attribute. This is the case when there are both a /// Clr wrapper and static Settor for a given DP. In that case we cache /// an object array of two elements. Also the MethodInfo for the given DP /// will be discovered first by the XamlReaderHelper while the PropertyInfo /// will be discovered by the BamlRecordWriter. /// </remarks> private MemberInfo GetCachedMemberInfo( Type owner, string propName, bool onlyPropInfo, out BamlAttributeInfoRecord infoRecord) { infoRecord = null; if (MapTable != null) { string fullName = owner.IsGenericType ? owner.Namespace + "." + owner.Name : owner.FullName; object key = MapTable.GetAttributeInfoKey(fullName, propName); infoRecord = MapTable.GetHashTableData(key) as BamlAttributeInfoRecord; if (infoRecord != null) { return infoRecord.GetPropertyMember(onlyPropInfo) as MemberInfo; } } return null; }
// // Set a property value that will go onto a DP // private void SetDependencyComplexProperty( object currentTarget, BamlAttributeInfoRecord attribInfo, object o) { DependencyProperty dp = currentTarget is DependencyObject ? attribInfo.DP : null; PropertyInfo propertyInfo = attribInfo.PropInfo; MethodInfo attachedPropertySetter = null; // postpone allocating a reflection data until necessary #if !STRESS try { #endif // ObjectData is either a DependencyProperty or a PropertyInfo. // Check if the object is a MarkupExtension. If so, then get the value // to set on this property from the MarkupExtension itself. MarkupExtension me = o as MarkupExtension; if (me != null) { // o = ProvideValueFromMarkupExtension(me, currentTarget, dp); } // Check if we have a Nullable type. If so and the object being set is // not a Nullable or an expression, then attempt a conversion. Type propertyType = null; if (dp != null) { propertyType = dp.PropertyType; } else if (propertyInfo != null) { propertyType = propertyInfo.PropertyType; } else { // Touching reflection information about the setter only now to avoid extra memory allocations if (attribInfo.AttachedPropertySetter == null) { XamlTypeMapper.UpdateAttachedPropertySetter(attribInfo); } attachedPropertySetter = attribInfo.AttachedPropertySetter; if (attachedPropertySetter != null) { propertyType = attachedPropertySetter.GetParameters()[1].ParameterType; } else { Debug.Assert(false); // } } o = OptionallyMakeNullable(propertyType, o, attribInfo.Name); // DependencyProperty, use the associated DependencyObject's SetValue. Otherwise // use the PropertyInfo's SetValue. if (dp != null) { Debug.Assert(currentTarget is DependencyObject); SetDependencyValue((DependencyObject)currentTarget, dp, o); } else if (propertyInfo != null) { propertyInfo.SetValue(currentTarget,o,BindingFlags.Default,null,null, TypeConverterHelper.InvariantEnglishUS); } else if (attachedPropertySetter != null) { attachedPropertySetter.Invoke(null, new object[] { currentTarget, o }); } else { Debug.Assert(false); // We do not expect to be here after all checks done in propertyType identification above } #if !STRESS } catch (Exception e) { if (CriticalExceptions.IsCriticalException(e) || e is XamlParseException) { throw; } TargetInvocationException tie = e as TargetInvocationException; if( tie != null ) { e = tie.InnerException; } ThrowExceptionWithLine(SR.Get(SRID.ParserCannotSetValue, currentTarget.GetType().FullName, attribInfo.Name, o), e); } #endif // The property has been set, so we do not expect any more child tags -- // anything more under this context will cause an error CurrentContext.ExpectedType = null; }