Skip to content

Commit d1b018c

Browse files
[Repo Assist] Fix decodeILCustomAttribData: resolve System.Type custom attribute arguments (#490)
🤖 *This PR was created by [Repo Assist](https://github.com/fsprojects/FSharp.TypeProviders.SDK/actions/runs/23774627661), an automated AI assistant.* ## Summary Fixes a long-standing TODO in `decodeILCustomAttribData` where custom attribute arguments of type `System.Type` were silently decoded as `null` instead of the actual `Type` object. ## Root Cause In ECMA-335, custom attribute constructors store `System.Type` arguments as serialised strings (the assembly-qualified type name) in the attribute blob — not as `TypeRef`/`TypeDef` table indices. The existing code parsed the type name string correctly via `ILTypeSigParser`, but then discarded the result and returned `null`: ```fsharp // Before — TODO comments, always returned null | None -> (argty, box null), sigptr // TODO: read System.Type attrs | Some n -> let parser = ILTypeSigParser(n) parser.ParseType() |> ignore (argty, box null), sigptr // TODO: read System.Type attributes ``` ## Fix 1. Added a `resolveILType: ILType -> Type` parameter to `decodeILCustomAttribData` so the caller provides a type resolver. 2. The `System.Type` branch now uses the parsed `ILType` and resolves it via the provided resolver. 3. Graceful fallback to `null` if resolution fails (e.g. the type is not present in the target context). 4. At the call site in `txCustomAttributesDatum`, passes `txILType ([||], [||])` — the existing target-assembly type translator — as the resolver. ```fsharp // After — resolves the type from the attribute blob | None -> (argty, box null), sigptr | Some n -> let parser = ILTypeSigParser(n) let ilty = parser.ParseType() let resolvedType = try resolveILType ilty with _ -> null (argty, box resolvedType), sigptr ``` ## Impact Custom attributes like `DebuggerTypeProxyAttribute` (constructor takes `Type`) that are read from binary reference assemblies via the target assembly reader now return the correct `Type` value instead of `null`. This improves the accuracy of `GetCustomAttributesData()` for target-context types. ## Test Status ✅ All 126 tests pass locally (`dotnet test tests/FSharp.TypeProviders.SDK.Tests.fsproj -c Release`) A dedicated test for this specific path would require finding a reference assembly type with a `System.Type` custom attribute argument and verifying it resolves non-null — feasible but deferred to a follow-up as it requires navigating the target context fixture. > Generated by 🌈 Repo Assist at [{run-started}](https://github.com/fsprojects/FSharp.TypeProviders.SDK/actions/runs/23774627661). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md). > > To install this [agentic workflow](https://github.com/githubnext/agentics/tree/1f672aef974f4246124860fc532f82fe8a93a57e/workflows/repo-assist.md), run > ``` > gh aw add githubnext/agentics@1f672ae > ``` <!-- gh-aw-agentic-workflow: Repo Assist, engine: copilot, model: auto, id: 23774627661, workflow_id: repo-assist, run: https://github.com/fsprojects/FSharp.TypeProviders.SDK/actions/runs/23774627661 --> <!-- gh-aw-workflow-id: repo-assist --> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 4b09aa2 commit d1b018c

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

src/ProvidedTypes.fs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6695,7 +6695,7 @@ module internal AssemblyReader =
66956695
let s, sigptr = sigptr_get_string len bytes sigptr
66966696
Some(s), sigptr
66976697

6698-
let decodeILCustomAttribData ilg (resolveEnumUnderlyingILType: ILType -> ILType) (ca: ILCustomAttribute) =
6698+
let decodeILCustomAttribData ilg (resolveEnumUnderlyingILType: ILType -> ILType) (resolveILType: ILType -> Type) (ca: ILCustomAttribute) =
66996699
let bytes = ca.Data
67006700
let sigptr = 0
67016701
let bb0, sigptr = sigptr_get_byte bytes sigptr
@@ -6748,12 +6748,13 @@ module internal AssemblyReader =
67486748
| ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Type" ->
67496749
let nOpt, sigptr = sigptr_get_serstring_possibly_null bytes sigptr
67506750
match nOpt with
6751-
| None -> (argty, box null) , sigptr // TODO: read System.Type attrs
6751+
| None -> (argty, box null), sigptr
67526752
| Some n ->
67536753
try
67546754
let parser = ILTypeSigParser(n)
6755-
parser.ParseType() |> ignore
6756-
(argty, box null) , sigptr // TODO: read System.Type attributes
6755+
let ilty = parser.ParseType()
6756+
let resolvedType = try resolveILType ilty with _ -> null
6757+
(argty, box resolvedType), sigptr
67576758
with e ->
67586759
failwithf "decodeILCustomAttribData: error parsing type in custom attribute blob: %s" e.Message
67596760
| ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "Object" ->
@@ -7697,7 +7698,7 @@ namespace ProviderImplementation.ProvidedTypes
76977698
else ilGlobals.typ_Int32
76987699
with _ -> ilGlobals.typ_Int32
76997700
| _ -> ilGlobals.typ_Int32
7700-
let args, namedArgs = decodeILCustomAttribData ilGlobals resolveEnumUnderlyingILType inp
7701+
let args, namedArgs = decodeILCustomAttribData ilGlobals resolveEnumUnderlyingILType (txILType ([| |], [| |])) inp
77017702
{ new CustomAttributeData () with
77027703
member __.Constructor = txILConstructorRef inp.Method.MethodRef
77037704
member __.ConstructorArguments = [| for arg in args -> txCustomAttributesArg arg |] :> IList<_>

0 commit comments

Comments
 (0)