internal Microsoft.Cci.IFieldReference Translate(FieldSymbol fieldSymbol, bool needDeclaration) { System.Diagnostics.Debug.Assert(ReferenceEquals(fieldSymbol, fieldSymbol.OriginalDefinition) || !fieldSymbol.Equals(fieldSymbol.OriginalDefinition)); if (!ReferenceEquals(fieldSymbol, fieldSymbol.OriginalDefinition)) { System.Diagnostics.Debug.Assert(!needDeclaration); return(fieldSymbol); } else if (!needDeclaration && IsGenericType(fieldSymbol.ContainingType)) { object reference; Microsoft.Cci.IFieldReference fieldRef; if (genericInstanceMap.TryGetValue(fieldSymbol, out reference)) { return((Microsoft.Cci.IFieldReference)reference); } fieldRef = new SpecializedFieldReference(fieldSymbol); genericInstanceMap.Add(fieldSymbol, fieldRef); return(fieldRef); } return(fieldSymbol); }
/// <summary> /// Given a field definition in the closure class, get its reference as will be used by the methods in the closure class. /// </summary> internal IFieldReference GetReferenceOfFieldUsedByPeers(IFieldDefinition fieldDef) { IFieldReference fieldReference = null; ITypeReference typeReference = this.ClosureDefinitionReference; ISpecializedNestedTypeReference nestedTypeRef = typeReference as ISpecializedNestedTypeReference; IGenericTypeInstanceReference genericTypeInstanceRef = typeReference as IGenericTypeInstanceReference; if (nestedTypeRef != null || genericTypeInstanceRef != null) { fieldReference = new SpecializedFieldReference() { ContainingType = typeReference, InternFactory = this.host.InternFactory, Name = fieldDef.Name, UnspecializedVersion = fieldDef, Type = fieldDef.Type }; } else fieldReference = fieldDef; return fieldReference; }
/// <summary> /// Given a field definition in the closure class, get its reference as will be used by the methods in the closure class. /// </summary> internal IFieldReference GetReferenceOfFieldUsedByPeers(IFieldDefinition fieldDef) { IFieldReference fieldReference = null; ITypeReference typeReference = this.ClosureDefinitionReference; ISpecializedNestedTypeReference nestedTypeRef = typeReference as ISpecializedNestedTypeReference; IGenericTypeInstanceReference genericTypeInstanceRef = typeReference as IGenericTypeInstanceReference; if (nestedTypeRef != null || genericTypeInstanceRef != null) { fieldReference = new SpecializedFieldReference() { ContainingType = typeReference, InternFactory = this.host.InternFactory, Name = fieldDef.Name, UnspecializedVersion = fieldDef, Type = fieldDef.Type }; } else { fieldReference = fieldDef; } return(fieldReference); }
/// <summary> /// Creates a field in the current closure class with the given type and name. /// If the current closure class is generic, the returned value is a reference /// to the corresponding field in the InstanceType of the current closure class. /// </summary> private void CreateClosureField(object capturedDefinition, ITypeReference fieldType, ITypeReference typeToUseInThisMethod, string name) { FieldDefinition field = new FieldDefinition() { ContainingTypeDefinition = this.currentClosureClass, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor(name), Type = fieldType, Visibility = TypeMemberVisibility.Public }; this.currentClosureClass.Fields.Add(field); if (this.currentClosureClass == this.currentClosureInstance) { //no generics this.fieldReferencesForUseInsideAnonymousMethods[capturedDefinition] = field; this.fieldReferencesForUseInsideThisMethod[capturedDefinition] = field; return; } var fieldRef = new SpecializedFieldReference() { ContainingType = this.currentClosureSelfInstance, //The type the closure uses to refer to itself InternFactory = this.host.InternFactory, Name = field.Name, Type = field.Type, UnspecializedVersion = field, }; this.fieldReferencesForUseInsideAnonymousMethods[capturedDefinition] = fieldRef; fieldRef = new SpecializedFieldReference() { ContainingType = this.currentClosureInstance, //The type this.method uses to refer to the closure. InternFactory = this.host.InternFactory, Name = field.Name, Type = typeToUseInThisMethod, UnspecializedVersion = field, }; this.fieldReferencesForUseInsideThisMethod[capturedDefinition] = fieldRef; }
//^ invariant this.PEFileReader.MethodSpecTable.NumberOfRows >= 1 ==> this.MethodSpecHashtable != null; internal ITypeMemberReference/*?*/ GetModuleMemberReferenceAtRowWorker( MetadataObject owningObject, uint memberRefRowId ) { if (memberRefRowId == 0 || memberRefRowId > this.PEFileReader.MemberRefTable.NumberOfRows) { return null; } if (this.ModuleMemberReferenceArray[memberRefRowId] == null) { MemberRefRow memberRefRow = this.PEFileReader.MemberRefTable[memberRefRowId]; uint classTokenType = memberRefRow.Class & TokenTypeIds.TokenTypeMask; uint classRowId = memberRefRow.Class & TokenTypeIds.RIDMask; ITypeReference/*?*/ parentTypeReference = null; switch (classTokenType) { case TokenTypeIds.TypeDef: parentTypeReference = this.GetTypeDefinitionAtRow(classRowId); break; case TokenTypeIds.TypeRef: parentTypeReference = this.GetTypeRefReferenceAtRow(classRowId); break; case TokenTypeIds.TypeSpec: parentTypeReference = this.GetTypeSpecReferenceAtRow(owningObject, classRowId).UnderlyingModuleTypeReference; break; case TokenTypeIds.MethodDef: { var/*?*/ methodDef = this.GetMethodDefAtRow(classRowId); if (methodDef == null) { // Error... return null; } parentTypeReference = methodDef.ContainingType; break; } case TokenTypeIds.ModuleRef: { ModuleReference/*?*/ modRef = this.GetModuleReferenceAt(classRowId); if (modRef == null) { // MDError return null; } var module = this.ResolveModuleRefReference(modRef) as Module; if (module == null) { //TODO: MDError... return null; } PEFileToObjectModel modulePEFileToObjectModel = module.PEFileToObjectModel; parentTypeReference = modulePEFileToObjectModel._Module_; break; } default: { // MDError... return null; } } if (parentTypeReference == null) { // Error... return null; } MemberReference retModuleMemberReference; IName name = this.GetNameFromOffset(memberRefRow.Name); byte firstByte = this.PEFileReader.BlobStream.GetByteAt(memberRefRow.Signature, 0); var genericTypeInstance = parentTypeReference as IGenericTypeInstanceReference; var specializedNestedTypeReference = parentTypeReference as ISpecializedNestedTypeReference; if (SignatureHeader.IsFieldSignature(firstByte)) { if (genericTypeInstance != null || specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore special caching is required FieldReference unspecializedFieldReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as FieldReference; if (unspecializedFieldReference == null) { unspecializedFieldReference = new FieldReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name); this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedFieldReference; } uint key1 = parentTypeReference.InternedKey; uint key2 = unspecializedFieldReference.InternedKey; var specializedField = this.SpecializedFieldHashtable.Find(key1, key2); if (specializedField == null) { specializedField = new SpecializedFieldReference(parentTypeReference, unspecializedFieldReference, this.InternFactory); this.SpecializedFieldHashtable.Add(key1, key2, specializedField); } return specializedField; } else { retModuleMemberReference = new FieldReference(this, memberRefRowId, parentTypeReference, name); } } else if (SignatureHeader.IsMethodSignature(firstByte)) { if (genericTypeInstance != null || specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore special caching is required MethodReference unspecializedMethodReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as MethodReference; if (unspecializedMethodReference == null) { unspecializedMethodReference = new MethodReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name, firstByte); this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedMethodReference; } uint key1 = parentTypeReference.InternedKey; uint key2 = unspecializedMethodReference.InternedKey; var specializedMethod = this.SpecializedMethodHashtable.Find(key1, key2); if (specializedMethod == null) { specializedMethod = new SpecializedMethodReference(parentTypeReference, unspecializedMethodReference, this.InternFactory); this.SpecializedMethodHashtable.Add(key1, key2, specializedMethod); } return specializedMethod; } else { retModuleMemberReference = new MethodReference(this, memberRefRowId, parentTypeReference, name, firstByte); } } else { // MD Error return null; } this.ModuleMemberReferenceArray[memberRefRowId] = retModuleMemberReference; } MemberReference/*?*/ ret = this.ModuleMemberReferenceArray[memberRefRowId]; return ret; }
internal Microsoft.Cci.IFieldReference Translate(FieldSymbol fieldSymbol, bool needDeclaration) { System.Diagnostics.Debug.Assert(ReferenceEquals(fieldSymbol, fieldSymbol.OriginalDefinition) || !fieldSymbol.Equals(fieldSymbol.OriginalDefinition)); if (!ReferenceEquals(fieldSymbol, fieldSymbol.OriginalDefinition)) { System.Diagnostics.Debug.Assert(!needDeclaration); return fieldSymbol; } else if (!needDeclaration && IsGenericType(fieldSymbol.ContainingType)) { object reference; Microsoft.Cci.IFieldReference fieldRef; if (genericInstanceMap.TryGetValue(fieldSymbol, out reference)) { return (Microsoft.Cci.IFieldReference)reference; } fieldRef = new SpecializedFieldReference(fieldSymbol); genericInstanceMap.Add(fieldSymbol, fieldRef); return fieldRef; } return fieldSymbol; }
/// <summary> /// Instantiate a closure class field using the generic method parameters of the iterator method, if any. /// Code Review: cache the result of GetClosureTypeReferenceFromIterator. /// </summary> /// <param name="iteratorClosure"></param> /// <param name="fieldDefinition"></param> /// <returns></returns> IFieldReference GetFieldReference(IteratorClosureInformation iteratorClosure, /*unspecialized*/IFieldDefinition fieldDefinition) { ITypeReference typeReference = GetClosureTypeReferenceFromIterator(iteratorClosure); IGenericTypeInstanceReference genericInstanceRef = typeReference as IGenericTypeInstanceReference; ISpecializedNestedTypeReference specializedNestedTypeRef = typeReference as ISpecializedNestedTypeReference; IFieldReference fieldReference = fieldDefinition; if (genericInstanceRef != null || specializedNestedTypeRef != null) { fieldReference = new SpecializedFieldReference() { ContainingType = typeReference, InternFactory = this.host.InternFactory, Name = fieldDefinition.Name, UnspecializedVersion = fieldDefinition, Type = fieldDefinition.Type }; } return fieldReference; }
/// <summary> /// Rewrites the given specialized field reference. /// </summary> /// <param name="fieldReference"></param> public override void RewriteChildren(SpecializedFieldReference fieldReference) { fieldReference.ContainingType = this.Rewrite(fieldReference.ContainingType); fieldReference.Type = this.Rewrite(fieldReference.Type); }