diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..9a77684 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + labels: + - "enhancement" diff --git a/src/ProvidedTypes.fs b/src/ProvidedTypes.fs index a6396a4..d7d50ae 100644 --- a/src/ProvidedTypes.fs +++ b/src/ProvidedTypes.fs @@ -2920,8 +2920,16 @@ module internal AssemblyReader = member x.IsRTSpecialName = (x.Attributes &&& EventAttributes.RTSpecialName) <> enum<_>(0) override x.ToString() = "event " + x.Name - type ILEventDefs = - abstract Entries: ILEventDef[] + type ILEventDefs(larr: Lazy) = + let lmap = lazy ( + let d = Dictionary() + for ev in larr.Force() do d.[ev.Name] <- ev + d) + member __.Entries = larr.Force() + member __.TryFindByName nm = + match lmap.Value.TryGetValue(nm) with + | true, ev -> Some ev + | _ -> None [] type ILPropertyDef = @@ -2947,8 +2955,16 @@ module internal AssemblyReader = member x.IsRTSpecialName = x.Attributes &&& PropertyAttributes.RTSpecialName <> enum 0 override x.ToString() = "property " + x.Name - type ILPropertyDefs = - abstract Entries: ILPropertyDef[] + type ILPropertyDefs(larr: Lazy) = + let lmap = lazy ( + let d = Dictionary() + for p in larr.Force() do d.[p.Name] <- p + d) + member __.Entries = larr.Force() + member __.TryFindByName nm = + match lmap.Value.TryGetValue(nm) with + | true, p -> Some p + | _ -> None [] type ILFieldDef = @@ -2980,8 +2996,16 @@ module internal AssemblyReader = override x.ToString() = "field " + x.Name - type ILFieldDefs = - abstract Entries: ILFieldDef[] + type ILFieldDefs(larr: Lazy) = + let lmap = lazy ( + let d = Dictionary() + for f in larr.Force() do d.[f.Name] <- f + d) + member __.Entries = larr.Force() + member __.TryFindByName nm = + match lmap.Value.TryGetValue(nm) with + | true, f -> Some f + | _ -> None type ILMethodImplDef = { Overrides: ILOverridesSpec @@ -4692,14 +4716,14 @@ module internal AssemblyReader = let td = ltd.Force() (td.Name, ltd) - let emptyILEvents = { new ILEventDefs with member __.Entries = [| |] } - let emptyILProperties = { new ILPropertyDefs with member __.Entries = [| |] } + let emptyILEvents = ILEventDefs(lazy [| |]) + let emptyILProperties = ILPropertyDefs(lazy [| |]) let emptyILTypeDefs = ILTypeDefs (lazy [| |]) let emptyILCustomAttrs = { new ILCustomAttrs with member __.Entries = [| |] } let mkILCustomAttrs x = { new ILCustomAttrs with member __.Entries = x } let emptyILMethodImpls = { new ILMethodImplDefs with member __.Entries = [| |] } let emptyILMethods = ILMethodDefs (lazy [| |]) - let emptyILFields = { new ILFieldDefs with member __.Entries = [| |] } + let emptyILFields = ILFieldDefs(lazy [| |]) let mkILTy boxed tspec = match boxed with @@ -5771,10 +5795,7 @@ module internal AssemblyReader = Token = idx } and seekReadFields (numtypars, hasLayout) fidx1 fidx2 = - { new ILFieldDefs with - member __.Entries = - [| for i = fidx1 to fidx2 - 1 do - yield seekReadField (numtypars, hasLayout) i |] } + ILFieldDefs(lazy [| for i = fidx1 to fidx2 - 1 do yield seekReadField (numtypars, hasLayout) i |]) and seekReadMethods numtypars midx1 midx2 = ILMethodDefs @@ -6100,9 +6121,9 @@ module internal AssemblyReader = Token = idx} and seekReadEvents numtypars tidx = - { new ILEventDefs with - member __.Entries = - match seekReadOptionalIndexedRow (getNumRows ILTableNames.EventMap, (fun i -> i, seekReadEventMapRow i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with + ILEventDefs + (lazy + (match seekReadOptionalIndexedRow (getNumRows ILTableNames.EventMap, (fun i -> i, seekReadEventMapRow i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with | None -> [| |] | Some (rowNum, beginEventIdx) -> let endEventIdx = @@ -6111,9 +6132,8 @@ module internal AssemblyReader = else let (_, endEventIdx) = seekReadEventMapRow (rowNum + 1) endEventIdx - [| for i in beginEventIdx .. endEventIdx - 1 do - yield seekReadEvent numtypars i |] } + yield seekReadEvent numtypars i |])) and seekReadProperty numtypars idx = let (flags, nameIdx, typIdx) = seekReadPropertyRow idx @@ -6139,9 +6159,9 @@ module internal AssemblyReader = Token = idx } and seekReadProperties numtypars tidx = - { new ILPropertyDefs with - member __.Entries = - match seekReadOptionalIndexedRow (getNumRows ILTableNames.PropertyMap, (fun i -> i, seekReadPropertyMapRow i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with + ILPropertyDefs + (lazy + (match seekReadOptionalIndexedRow (getNumRows ILTableNames.PropertyMap, (fun i -> i, seekReadPropertyMapRow i), (fun (_, row) -> fst row), compare tidx, false, (fun (i, row) -> (i, snd row))) with | None -> [| |] | Some (rowNum, beginPropIdx) -> let endPropIdx = @@ -6151,7 +6171,7 @@ module internal AssemblyReader = let (_, endPropIdx) = seekReadPropertyMapRow (rowNum + 1) endPropIdx [| for i in beginPropIdx .. endPropIdx - 1 do - yield seekReadProperty numtypars i |] } + yield seekReadProperty numtypars i |])) and seekReadCustomAttrs idx = @@ -7514,7 +7534,7 @@ namespace ProviderImplementation.ProvidedTypes override this.GetField(name, bindingFlags) = match kind with | TypeSymbolKind.TargetGeneric gtd -> - gtd.Metadata.Fields.Entries |> Array.tryFind (fun md -> md.Name = name) + gtd.Metadata.Fields.TryFindByName name |> Option.map (gtd.MakeFieldInfo this) |> Option.toObj | TypeSymbolKind.OtherGeneric gtd -> @@ -7528,8 +7548,7 @@ namespace ProviderImplementation.ProvidedTypes override this.GetPropertyImpl(name, bindingFlags, _binder, _returnType, _types, _modifiers) = match kind with | TypeSymbolKind.TargetGeneric gtd -> - gtd.Metadata.Properties.Entries - |> Array.tryFind (fun md -> md.Name = name) + gtd.Metadata.Properties.TryFindByName name |> Option.map (gtd.MakePropertyInfo this) |> Option.toObj | TypeSymbolKind.OtherGeneric gtd -> @@ -7543,8 +7562,7 @@ namespace ProviderImplementation.ProvidedTypes override this.GetEvent(name, bindingFlags) = match kind with | TypeSymbolKind.TargetGeneric gtd -> - gtd.Metadata.Events.Entries - |> Array.tryFind (fun md -> md.Name = name) + gtd.Metadata.Events.TryFindByName name |> Option.map (gtd.MakeEventInfo this) |> Option.toObj | TypeSymbolKind.OtherGeneric gtd -> @@ -7994,6 +8012,20 @@ namespace ProviderImplementation.ProvidedTypes let propDefs = lazy (inp.Properties.Entries |> Array.map (txILPropertyDef this)) let nestedDefs = lazy (inp.NestedTypes.Entries |> Array.map (asm.TxILTypeDef (Some (this :> Type)))) + // Lazy dictionaries for O(1) single-member lookup by name. + let fieldDefsMap = + lazy (let d = Dictionary() + for f in fieldDefs.Force() do d.[f.Name] <- f + d) + let propDefsMap = + lazy (let d = Dictionary() + for p in propDefs.Force() do d.[p.Name] <- p + d) + let eventDefsMap = + lazy (let d = Dictionary() + for e in eventDefs.Force() do d.[e.Name] <- e + d) + // Cache derived properties that are computed from immutable input data. // The F# compiler may call FullName, BaseType and GetInterfaces() many times per type // during type-checking; caching avoids repeated string allocations and type-resolution work. @@ -8063,13 +8095,19 @@ namespace ProviderImplementation.ProvidedTypes md |> Option.map (txILMethodDef this) |> Option.toObj override this.GetField(name, _bindingFlags) = - fieldDefs.Force() |> Array.tryFind (fun f -> f.Name = name) |> Option.toObj + match fieldDefsMap.Value.TryGetValue(name) with + | true, f -> f + | _ -> null override this.GetPropertyImpl(name, _bindingFlags, _binder, _returnType, _types, _modifiers) = - propDefs.Force() |> Array.tryFind (fun p -> p.Name = name) |> Option.toObj + match propDefsMap.Value.TryGetValue(name) with + | true, p -> p + | _ -> null override this.GetEvent(name, _bindingFlags) = - eventDefs.Force() |> Array.tryFind (fun ev -> ev.Name = name) |> Option.toObj + match eventDefsMap.Value.TryGetValue(name) with + | true, ev -> ev + | _ -> null override this.GetNestedType(name, _bindingFlags) = inp.NestedTypes.TryFindByName(UNone, name) |> Option.map (asm.TxILTypeDef (Some (this :> Type))) |> Option.toObj @@ -8107,7 +8145,7 @@ namespace ProviderImplementation.ProvidedTypes if this.IsEnum then // Read the underlying type from the special "value__" field that the compiler emits for every enum. // This correctly handles non-Int32 backing types (byte, int16, int64, etc.). - let valueField = inp.Fields.Entries |> Array.tryFind (fun f -> f.Name = "value__") + let valueField = inp.Fields.TryFindByName "value__" match valueField with | Some f -> txILType ([| |], [| |]) f.FieldType | None -> txILType ([| |], [| |]) ilGlobals.typ_Int32 @@ -9285,7 +9323,7 @@ namespace ProviderImplementation.ProvidedTypes if i < 0 then let msg = if toTgt then sprintf "The design-time type '%O' utilized by a type provider was not found in the target reference assembly set '%A'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using." t (getTargetAssemblies() |> Seq.toList) - elif getSourceAssemblies() |> Seq.isEmpty then sprintf "A failure occured while determining compilation references" + elif getSourceAssemblies() |> Seq.isEmpty then sprintf "A failure occurred while determining compilation references" else sprintf "The target type '%O' utilized by a type provider was not found in the design-time assembly set '%A'. Please report this problem to the project site for the type provider." t (getSourceAssemblies() |> Seq.toList) failwith msg else @@ -14111,9 +14149,9 @@ namespace ProviderImplementation.ProvidedTypes //SecurityDecls=emptyILSecurityDecls; //HasSecurity=false; NestedTypes = ILTypeDefs( lazy [| for x in nestedTypes -> let td = x.Content in td.Namespace, td.Name, lazy td |] ) - Fields = { new ILFieldDefs with member __.Entries = [| for x in fields -> x.Content |] } - Properties = { new ILPropertyDefs with member __.Entries = [| for x in props -> x.Content |] } - Events = { new ILEventDefs with member __.Entries = [| for x in events -> x.Content |] } + Fields = ILFieldDefs(lazy [| for x in fields -> x.Content |]) + Properties = ILPropertyDefs(lazy [| for x in props -> x.Content |]) + Events = ILEventDefs(lazy [| for x in events -> x.Content |]) Methods = ILMethodDefs (lazy [| for x in methods -> x.Content |]) MethodImpls = { new ILMethodImplDefs with member __.Entries = methodImpls.ToArray() } CustomAttrs = mkILCustomAttrs (cattrs.ToArray())