@@ -858,10 +858,10 @@ let hsCompare (TaggedIndex(t1: HasSemanticsTag, idx1: int)) (TaggedIndex(t2: Has
858858 elif idx1 > idx2 then 1
859859 else compare t1.Tag t2.Tag
860860
861- let hcaCompare ( TaggedIndex ( t1 : HasCustomAttributeTag , idx1 : int )) ( TaggedIndex ( t2 : HasCustomAttributeTag , idx2 ) ) =
862- if idx1 < idx2 then - 1
863- elif idx1 > idx2 then 1
864- else compare t1.Tag t2.Tag
861+ let inline hcaCompare ( t1 : TaggedIndex < HasCustomAttributeTag >) ( t2 : TaggedIndex < HasCustomAttributeTag > ) =
862+ if t1.index < t2.index then - 1
863+ elif t1.index > t2.index then 1
864+ else compare t1.tag t2.tag
865865
866866let mfCompare ( TaggedIndex ( t1 : MemberForwardedTag , idx1 : int )) ( TaggedIndex ( t2 : MemberForwardedTag , idx2 )) =
867867 if idx1 < idx2 then - 1
@@ -2112,9 +2112,82 @@ and typeDefReader ctxtH : ILTypeDefStored =
21122112 let layout = typeLayoutOfFlags ctxt mdv flags idx
21132113
21142114 let hasLayout =
2115- ( match layout with
2116- | ILTypeDefLayout.Explicit _ -> true
2117- | _ -> false )
2115+ match layout with
2116+ | ILTypeDefLayout.Explicit _ -> true
2117+ | _ -> false
2118+
2119+ let containsExtensionMethods =
2120+ let mutable containsExtensionMethods = false
2121+ let searchedKey = TaggedIndex( hca_ TypeDef, idx)
2122+
2123+ let attributesSearcher =
2124+ { new ISeekReadIndexedRowReader< int, int, int> with
2125+ member _. GetRow( i, rowIndex) = rowIndex <- i
2126+ member _. GetKey( rowIndex) = rowIndex
2127+
2128+ member _. CompareKey( rowIndex) =
2129+ let mutable addr = ctxt.rowAddr TableNames.CustomAttribute rowIndex
2130+ // read parentIndex
2131+ let key = seekReadHasCustomAttributeIdx ctxt mdv & addr
2132+ hcaCompare searchedKey key
2133+
2134+ member _. ConvertRow( i) = i
2135+ }
2136+
2137+ let attrsStartIdx , attrsEndIdx =
2138+ seekReadIndexedRowsRange
2139+ ( ctxt.getNumRows TableNames.CustomAttribute)
2140+ ( isSorted ctxt TableNames.CustomAttribute)
2141+ attributesSearcher
2142+
2143+ if attrsStartIdx <= 0 || attrsEndIdx < attrsStartIdx then
2144+ false
2145+ else
2146+ let mutable attrIdx = attrsStartIdx
2147+
2148+ let looksLikeSystemAssembly =
2149+ ctxt.fileName.EndsWith( " System.Runtime.dll" )
2150+ || ctxt.fileName.EndsWith( " mscorlib.dll" )
2151+ || ctxt.fileName.EndsWith( " netstandard.dll" )
2152+
2153+ while attrIdx <= attrsEndIdx && not containsExtensionMethods do
2154+ let mutable addr = ctxt.rowAddr TableNames.CustomAttribute attrIdx
2155+ // skip parentIndex to read typeIndex
2156+ seekReadHasCustomAttributeIdx ctxt mdv & addr |> ignore
2157+ let attrTypeIndex = seekReadCustomAttributeTypeIdx ctxt mdv & addr
2158+ let attrCtorIdx = attrTypeIndex.index
2159+
2160+ let name =
2161+ if attrTypeIndex.tag = cat_ MethodDef then
2162+ // the ExtensionAttribute constructor can be cat_MethodDef if the metadata is read from the assembly
2163+ // in which the corresponding attribute is defined -- from the system library
2164+ if not looksLikeSystemAssembly then
2165+ " "
2166+ else
2167+ let _ , ( _ , nameIdx , namespaceIdx , _ , _ , _ ) = seekMethodDefParent ctxt attrCtorIdx
2168+ readBlobHeapAsTypeName ctxt ( nameIdx, namespaceIdx)
2169+ else
2170+ let mutable addr = ctxt.rowAddr TableNames.MemberRef attrCtorIdx
2171+ let mrpTag = seekReadMemberRefParentIdx ctxt mdv & addr
2172+
2173+ if mrpTag.tag <> mrp_ TypeRef then
2174+ " "
2175+ else
2176+ let _ , nameIdx , namespaceIdx = seekReadTypeRefRow ctxt mdv mrpTag.index
2177+ readBlobHeapAsTypeName ctxt ( nameIdx, namespaceIdx)
2178+
2179+ if name = " System.Runtime.CompilerServices.ExtensionAttribute" then
2180+ containsExtensionMethods <- true
2181+
2182+ attrIdx <- attrIdx + 1
2183+
2184+ containsExtensionMethods
2185+
2186+ let additionalFlags =
2187+ if containsExtensionMethods then
2188+ ILTypeDefAdditionalFlags.CanContainExtensionMethods
2189+ else
2190+ ILTypeDefAdditionalFlags.None
21182191
21192192 let mdefs = seekReadMethods ctxt numTypars methodsIdx endMethodsIdx
21202193 let fdefs = seekReadFields ctxt ( numTypars, hasLayout) fieldsIdx endFieldsIdx
@@ -2138,7 +2211,7 @@ and typeDefReader ctxtH : ILTypeDefStored =
21382211 methodImpls = mimpls,
21392212 events = events,
21402213 properties = props,
2141- isKnownToBeAttribute = false ,
2214+ additionalFlags = additionalFlags ,
21422215 customAttrsStored = ctxt.customAttrsReader_ TypeDef,
21432216 metadataIndex = idx
21442217 ))
@@ -2797,22 +2870,26 @@ and seekReadMemberRefAsFieldSpecUncached ctxtH (MemberRefAsFspecIdx(numTypars, i
27972870// method-range and field-range start/finish indexes
27982871and seekReadMethodDefAsMethodData ctxt idx = ctxt.seekReadMethodDefAsMethodData idx
27992872
2873+ and seekMethodDefParent ( ctxt : ILMetadataReader ) methodIdx =
2874+ seekReadIndexedRow (
2875+ ctxt.getNumRows TableNames.TypeDef,
2876+ ( fun i -> i, seekReadTypeDefRow ctxt i),
2877+ id,
2878+ ( fun ( i , ( _ , _ , _ , _ , _ , methodsIdx as info )) ->
2879+ if methodsIdx > methodIdx then
2880+ - 1
2881+ else
2882+ let struct ( _ , endMethodsIdx ) = seekReadTypeDefRowExtents ctxt info i
2883+ if endMethodsIdx <= methodIdx then 1 else 0 ),
2884+ true ,
2885+ id
2886+ )
2887+
28002888and seekReadMethodDefAsMethodDataUncached ctxtH idx =
28012889 let ( ctxt : ILMetadataReader ) = getHole ctxtH
28022890 let mdv = ctxt.mdfile.GetView()
28032891 // Look for the method def parent.
2804- let tidx =
2805- seekReadIndexedRow (
2806- ctxt.getNumRows TableNames.TypeDef,
2807- ( fun i -> i, seekReadTypeDefRowWithExtents ctxt i),
2808- id,
2809- ( fun ( _ , (( _ , _ , _ , _ , _ , methodsIdx ), ( _ , endMethodsIdx ))) ->
2810- if endMethodsIdx <= idx then 1
2811- elif methodsIdx <= idx && idx < endMethodsIdx then 0
2812- else - 1 ),
2813- true ,
2814- fst
2815- )
2892+ let tidx , _ = seekMethodDefParent ctxt idx
28162893 // Create a formal instantiation if needed
28172894 let typeGenericArgs = seekReadGenericParams ctxt 0 ( tomd_ TypeDef, tidx)
28182895 let typeGenericArgsCount = typeGenericArgs.Length
0 commit comments