未验证 提交 c11ccaad 编写于 作者: F Florian Verdonck 提交者: GitHub

Replace Map with Dictionary (#13044)

上级 b822e279
......@@ -5,6 +5,7 @@ module internal FSharp.Compiler.Import
open System.Collections.Concurrent
open System.Collections.Generic
open System.Collections.Immutable
open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
open FSharp.Compiler
......@@ -586,25 +587,60 @@ let ImportILAssemblyTypeDefs (amap, m, auxModLoader, aref, mainmod: ILModuleDef)
CombineCcuContentFragments m (mainmod :: mtypsForExportedTypes)
/// Import the type forwarder table for an IL assembly
let ImportILAssemblyTypeForwarders (amap, m, exportedTypes: ILExportedTypesAndForwarders) =
// Note 'td' may be in another module or another assembly!
// Note: it is very important that we call auxModLoader lazily
[ //printfn "reading forwarders..."
for exportedType in exportedTypes.AsList() do
let ImportILAssemblyTypeForwarders (amap, m, exportedTypes: ILExportedTypesAndForwarders): CcuTypeForwarderTable =
let rec addToTree tree path item value =
match path with
| [] ->
{ tree with
Children =
tree.Children.Add(
item,
{ Value = Some value
Children = ImmutableDictionary.Empty }
) }
| nodeKey :: rest ->
match tree.Children.TryGetValue(nodeKey) with
| true, subTree -> { tree with Children = tree.Children.SetItem(nodeKey, addToTree subTree rest item value) }
| false, _ -> { tree with Children = tree.Children.Add(nodeKey, mkTreeWith rest item value) }
and mkTreeWith path item value =
match path with
| [] ->
{ Value = None
Children =
ImmutableDictionary.Empty.Add(
item,
{ Value = Some value
Children = ImmutableDictionary.Empty }
) }
| nodeKey :: rest ->
{ Value = None
Children = ImmutableDictionary.Empty.Add(nodeKey, mkTreeWith rest item value) }
let rec addNested
(exportedType: ILExportedTypeOrForwarder)
(nets: ILNestedExportedTypes)
(enc: string list)
(tree: CcuTypeForwarderTree<string, Lazy<EntityRef>>)
: CcuTypeForwarderTree<string, Lazy<EntityRef>> =
(tree, nets.AsList())
||> List.fold(fun tree net ->
let tcref = lazy ImportILTypeRefUncached (amap ()) m (ILTypeRef.Create(exportedType.ScopeRef, enc, net.Name))
addToTree tree enc exportedType.Name tcref
|> addNested exportedType net.Nested [yield! enc; yield net.Name])
match exportedTypes.AsList() with
| [] -> CcuTypeForwarderTable.Empty
| rootTypes ->
({ Value = None; Children = ImmutableDictionary.Empty } , rootTypes)
||> List.fold(fun tree exportedType ->
let ns, n = splitILTypeName exportedType.Name
//printfn "found forwarder for %s..." n
let tcref = lazy ImportILTypeRefUncached (amap()) m (ILTypeRef.Create(exportedType.ScopeRef, [], exportedType.Name))
yield (Array.ofList ns, n), tcref
let rec nested (nets: ILNestedExportedTypes) enc =
[ for net in nets.AsList() do
//printfn "found nested forwarder for %s..." net.Name
let tcref = lazy ImportILTypeRefUncached (amap()) m (ILTypeRef.Create (exportedType.ScopeRef, enc, net.Name))
yield (Array.ofList enc, exportedType.Name), tcref
yield! nested net.Nested (enc @ [ net.Name ]) ]
yield! nested exportedType.Nested (ns@[n])
] |> Map.ofList
let tcref = lazy ImportILTypeRefUncached (amap ()) m (ILTypeRef.Create(exportedType.ScopeRef, [], exportedType.Name))
addToTree tree ns n tcref
|> addNested exportedType exportedType.Nested [yield! ns; yield n]
)
|> fun root -> { Root = root }
/// Import an IL assembly as a new TAST CCU
let ImportILAssembly(amap: unit -> ImportMap, m, auxModuleLoader, xmlDocInfoLoader: IXmlDocumentationInfoLoader option, ilScopeRef, sourceDir, fileName, ilModule: ILModuleDef, invalidateCcu: IEvent<string>) =
invalidateCcu |> ignore
......@@ -616,7 +652,7 @@ let ImportILAssembly(amap: unit -> ImportMap, m, auxModuleLoader, xmlDocInfoLoad
let mty = ImportILAssemblyTypeDefs(amap, m, auxModuleLoader, aref, ilModule)
let forwarders =
match ilModule.Manifest with
| None -> Map.empty
| None -> CcuTypeForwarderTable.Empty
| Some manifest -> ImportILAssemblyTypeForwarders(amap, m, manifest.ExportedTypes)
let ccuData: CcuData =
......
......@@ -3,6 +3,7 @@
/// Functions to import .NET binary metadata as TAST objects
module internal FSharp.Compiler.Import
open System.Collections.Immutable
open Internal.Utilities.Library
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.TcGlobals
......@@ -96,7 +97,7 @@ val internal ImportILAssembly:
/// Import the type forwarder table for an IL assembly
val internal ImportILAssemblyTypeForwarders:
(unit -> ImportMap) * range * ILExportedTypesAndForwarders -> Map<string array * string, Lazy<EntityRef>>
(unit -> ImportMap) * range * ILExportedTypesAndForwarders -> CcuTypeForwarderTable
/// Import an IL type as an F# type, first rescoping to view the metadata from the current assembly
/// being compiled. importInst gives the context for interpreting type variables.
......
......@@ -6,6 +6,7 @@ module internal FSharp.Compiler.CompilerImports
open System
open System.Collections.Generic
open System.Collections.Immutable
open System.Diagnostics
open System.IO
......@@ -1114,7 +1115,7 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
MemberSignatureEquality = (fun ty1 ty2 -> typeEquivAux EraseAll g ty1 ty2)
ImportProvidedType = (fun ty -> ImportProvidedType (tcImports.GetImportMap()) m ty)
TryGetILModuleDef = (fun () -> Some ilModule)
TypeForwarders = Map.empty
TypeForwarders = CcuTypeForwarderTable.Empty
XmlDocumentationInfo =
match tcConfig.xmlDocInfoLoader with
| Some xmlDocInfoLoader -> xmlDocInfoLoader.TryLoad(fileName)
......
......@@ -5,6 +5,7 @@ module internal FSharp.Compiler.ParseAndCheckInputs
open System
open System.IO
open System.Collections.Generic
open Internal.Utilities.Collections
open Internal.Utilities.Library
......@@ -727,7 +728,7 @@ let CheckSimulateException(tcConfig: TcConfig) =
| Some("tc-oe") -> raise(OverflowException())
| Some("tc-atmm") -> raise(ArrayTypeMismatchException())
| Some("tc-bif") -> raise(BadImageFormatException())
| Some("tc-knf") -> raise(System.Collections.Generic.KeyNotFoundException())
| Some("tc-knf") -> raise(KeyNotFoundException())
| Some("tc-ior") -> raise(IndexOutOfRangeException())
| Some("tc-ic") -> raise(InvalidCastException())
| Some("tc-ip") -> raise(InvalidProgramException())
......@@ -808,7 +809,7 @@ let GetInitialTcState(m, ccuName, tcConfig: TcConfig, tcGlobals, tcImports: TcIm
ILScopeRef=ILScopeRef.Local
Contents=ccuContents
MemberSignatureEquality= typeEquivAux EraseAll tcGlobals
TypeForwarders=Map.empty
TypeForwarders= CcuTypeForwarderTable.Empty
XmlDocumentationInfo = None }
let ccu = CcuThunk.Create(ccuName, ccuData)
......
......@@ -4,7 +4,8 @@
module internal rec FSharp.Compiler.TypedTree
open System
open System.Collections.Generic
open System.Collections.Generic
open System.Collections.Immutable
open System.Diagnostics
open System.Reflection
......@@ -5291,8 +5292,39 @@ type CcuData =
override x.ToString() = sprintf "CcuData(%A)" x.FileName
type CcuTypeForwarderTree<'TKey, 'TValue> =
{
Value : 'TValue option
Children : ImmutableDictionary<'TKey, CcuTypeForwarderTree<'TKey, 'TValue>>
}
static member Empty = { Value = None; Children = ImmutableDictionary.Empty }
module CcuTypeForwarderTable =
let rec findInTree (remainingPath: ArraySegment<string>) (finalKey : string) (tree:CcuTypeForwarderTree<string, Lazy<EntityRef>>): Lazy<EntityRef> option =
let nodes = tree.Children
let searchTerm =
if remainingPath.Count = 0 then
finalKey
else
remainingPath.Array.[remainingPath.Offset]
match nodes.TryGetValue searchTerm with
| true, innerTree ->
if remainingPath.Count = 0 then
innerTree.Value
else
findInTree (ArraySegment<string>(remainingPath.Array, remainingPath.Offset + 1, remainingPath.Count - 1)) finalKey innerTree
| false, _ -> None
/// Represents a table of .NET CLI type forwarders for an assembly
type CcuTypeForwarderTable = Map<string[] * string, Lazy<EntityRef>>
type CcuTypeForwarderTable =
{
Root : CcuTypeForwarderTree<string, Lazy<EntityRef>>
}
static member Empty : CcuTypeForwarderTable = { Root = CcuTypeForwarderTree<_,_>.Empty }
member this.TryGetValue (path:string array) (item:string): Lazy<EntityRef> option =
CcuTypeForwarderTable.findInTree (ArraySegment path) item this.Root
type CcuReference = string // ILAssemblyRef
......@@ -5381,7 +5413,7 @@ type CcuThunk =
member ccu.Contents = ccu.Deref.Contents
/// The table of type forwarders for this assembly
member ccu.TypeForwarders: Map<string[] * string, Lazy<EntityRef>> = ccu.Deref.TypeForwarders
member ccu.TypeForwarders: CcuTypeForwarderTable = ccu.Deref.TypeForwarders
/// The table of modules and namespaces at the "root" of the assembly
member ccu.RootModulesAndNamespaces = ccu.Contents.ModuleOrNamespaceType.ModuleAndNamespaceDefinitions
......@@ -5418,10 +5450,8 @@ type CcuThunk =
/// Try to resolve a path into the CCU by referencing the .NET/CLI type forwarder table of the CCU
member ccu.TryForward(nlpath: string[], item: string) : EntityRef option =
ccu.EnsureDerefable nlpath
let key = nlpath, item
match ccu.TypeForwarders.TryGetValue key with
| true, entity -> Some(entity.Force())
| _ -> None
ccu.TypeForwarders.TryGetValue nlpath item
|> Option.map (fun entity -> entity.Force())
/// Used to make forward calls into the type/assembly loader when comparing member signatures during linking
member ccu.MemberSignatureEquality(ty1: TType, ty2: TType) =
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Compiler\FSharp.Compiler.Service.fsproj" />
</ItemGroup>
</Project>
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册