提交 70e27ac8 编写于 作者: E Eugene Auduchinok 提交者: Kevin Ransom (msft)

Replace subsequent ContainsKey and Item calls with TryGetValue matches (#4731)

Thanks for this.
上级 5a24b354
......@@ -173,7 +173,13 @@ type LazyOrderedMultiMap<'Key,'Data when 'Key : equality>(keyf : 'Data -> 'Key,
let quickMap=
lazyItems |> lazyMap (fun entries ->
let t = new Dictionary<_,_>(entries.Length, HashIdentity.Structural)
do entries |> List.iter (fun y -> let key = keyf y in t.[key] <- y :: (if t.ContainsKey(key) then t.[key] else []))
do entries |> List.iter (fun y ->
let key = keyf y
let v =
match t.TryGetValue(key) with
| true, v -> v
| _ -> []
t.[key] <- y :: v)
t)
member self.Entries() = lazyItems.Force()
......@@ -182,7 +188,11 @@ type LazyOrderedMultiMap<'Key,'Data when 'Key : equality>(keyf : 'Data -> 'Key,
member self.Filter(f) = new LazyOrderedMultiMap<'Key,'Data>(keyf, lazyItems |> lazyMap (List.filter f))
member self.Item with get(x) = let t = quickMap.Force() in if t.ContainsKey x then t.[x] else []
member self.Item
with get(x) =
match quickMap.Force().TryGetValue(x) with
| true, v -> v
| _ -> []
//---------------------------------------------------------------------
......@@ -1535,10 +1545,9 @@ type ILMethodDefs(f : (unit -> ILMethodDef[])) =
for i = arr.Length - 1 downto 0 do
let y = arr.[i]
let key = y.Name
if t.ContainsKey key then
t.[key] <- y :: t.[key]
else
t.[key] <- [ y ]
match t.TryGetValue(key) with
| true, m -> t.[key] <- y :: m
| _ -> t.[key] <- [y]
t)
interface IEnumerable with
......@@ -1549,7 +1558,12 @@ type ILMethodDefs(f : (unit -> ILMethodDef[])) =
member x.AsArray = array.Value
member x.AsList = array.Value|> Array.toList
member x.FindByName nm = if dict.Value.ContainsKey nm then dict.Value.[nm] else []
member x.FindByName(nm) =
match dict.Value.TryGetValue(nm) with
| true, m -> m
| _ -> []
member x.FindByNameAndArity (nm,arity) = x.FindByName nm |> List.filter (fun x -> List.length x.Parameters = arity)
[<NoComparison; NoEquality>]
......
......@@ -907,11 +907,10 @@ let _ = eventually { use x = null in return 1 }
type UniqueStampGenerator<'T when 'T : equality>() =
let encodeTab = new Dictionary<'T,int>(HashIdentity.Structural)
let mutable nItems = 0
let encode str =
if encodeTab.ContainsKey(str)
then
encodeTab.[str]
else
let encode str =
match encodeTab.TryGetValue(str) with
| true, idx -> idx
| _ ->
let idx = nItems
encodeTab.[str] <- idx
nItems <- nItems + 1
......
......@@ -925,8 +925,14 @@ let mkCacheGeneric lowMem _inbase _nm _sz =
| null -> cache := new Dictionary<_, _>(11 (* sz:int *) )
| _ -> ()
!cache
if cache.ContainsKey idx then (incr count; cache.[idx])
else let res = f idx in cache.[idx] <- res; res
match cache.TryGetValue(idx) with
| true, v ->
incr count
v
| _ ->
let res = f idx
cache.[idx] <- res
res
//-----------------------------------------------------------------------
// Polymorphic general helpers for searching for particular rows.
......@@ -2652,11 +2658,10 @@ and seekReadImplMap (ctxt: ILMetadataReader) nm midx =
and seekReadTopCode (ctxt: ILMetadataReader) pev mdv numtypars (sz:int) start seqpoints =
let labelsOfRawOffsets = new Dictionary<_, _>(sz/2)
let ilOffsetsOfLabels = new Dictionary<_, _>(sz/2)
let tryRawToLabel rawOffset =
if labelsOfRawOffsets.ContainsKey rawOffset then
Some(labelsOfRawOffsets.[rawOffset])
else
None
let tryRawToLabel rawOffset =
match labelsOfRawOffsets.TryGetValue(rawOffset) with
| true, v -> Some v
| _ -> None
let rawToLabel rawOffset =
match tryRawToLabel rawOffset with
......@@ -3092,11 +3097,9 @@ and seekReadMethodRVA (pectxt: PEReader) (ctxt: ILMetadataReader) (idx, nm, _int
end
let key = (tryStart, tryFinish)
if sehMap.ContainsKey key then
let prev = sehMap.[key]
sehMap.[key] <- (prev @ [clause])
else
sehMap.[key] <- [clause])
match sehMap.TryGetValue(key) with
| true, prev -> sehMap.[key] <- prev @ [clause]
| _ -> sehMap.[key] <- [clause])
clauses
([], sehMap) ||> Seq.fold (fun acc (KeyValue(key, bs)) -> [ for b in bs -> {Range=key; Clause=b} : ILExceptionSpec ] @ acc)
seh := sehClauses
......@@ -3295,7 +3298,10 @@ let getPdbReader pdbPath fileName =
documentType = Some (pdbDocumentGetType pdbdoc),
file = url))
let docfun url = if tab.ContainsKey url then tab.[url] else failwith ("Document with URL "+url+" not found in list of documents in the PDB file")
let docfun url =
match tab.TryGetValue(url) with
| true, doc -> doc
| _ -> failwith ("Document with URL " + url + " not found in list of documents in the PDB file")
Some (pdbr, docfun)
with e -> dprintn ("* Warning: PDB file could not be read and will be ignored: "+e.Message); None
#endif
......
......@@ -1317,7 +1317,10 @@ let emitCode cenv modB emEnv (ilG:ILGenerator) (code: ILCode) =
let emEnv =
(emEnv, code.Labels) ||> Seq.fold (fun emEnv (KeyValue(label, pc)) ->
let lab = ilG.DefineLabelAndLog()
pc2lab.[pc] <- (if pc2lab.ContainsKey pc then lab :: pc2lab.[pc] else [lab])
pc2lab.[pc] <-
match pc2lab.TryGetValue(pc) with
| true, labels -> lab :: labels
| _ -> [lab]
envSetLabel emEnv label lab)
// Build a table that contains the operations that define where exception handlers are
......@@ -1325,7 +1328,10 @@ let emitCode cenv modB emEnv (ilG:ILGenerator) (code: ILCode) =
let lab2pc = code.Labels
let add lab action =
let pc = lab2pc.[lab]
pc2action.[pc] <- (if pc2action.ContainsKey pc then pc2action.[pc] @ [ action ] else [ action ])
pc2action.[pc] <-
match pc2action.TryGetValue(pc) with
| true, actions -> actions @ [action]
| _ -> [action]
for e in code.Exceptions do
let (startTry, _endTry) = e.Range
......@@ -1354,12 +1360,18 @@ let emitCode cenv modB emEnv (ilG:ILGenerator) (code: ILCode) =
let instrs = code.Instrs
for pc = 0 to instrs.Length do
if pc2action.ContainsKey pc then
for action in pc2action.[pc] do
match pc2action.TryGetValue(pc) with
| true, actions ->
for action in actions do
action()
if pc2lab.ContainsKey pc then
for lab in pc2lab.[pc] do
ilG.MarkLabelAndLog lab
| _ -> ()
match pc2lab.TryGetValue(pc) with
| true, labels ->
for lab in labels do
ilG.MarkLabelAndLog(lab)
| _ -> ()
if pc < instrs.Length then
match instrs.[pc] with
| I_br l when code.Labels.[l] = pc + 1 -> () // compress I_br to next instruction
......
......@@ -1643,9 +1643,10 @@ module Codebuf =
// a safe approximation because code only gets smaller.
if not (origAvailBrFixups.ContainsKey tg) then
dprintn ("branch target " + formatCodeLabel tg + " not found in code")
let origDest =
if origAvailBrFixups.ContainsKey tg then origAvailBrFixups.[tg]
else 666666
let origDest =
match origAvailBrFixups.TryGetValue(tg) with
| true, fixup -> fixup
| _ -> 666666
let origRelOffset = origDest - origEndOfInstr
-128 <= origRelOffset && origRelOffset <= 127
end
......@@ -1718,18 +1719,16 @@ module Codebuf =
// Now apply the adjusted fixups in the new code
newReqdBrFixups |> List.iter (fun (newFixupLoc, endOfInstr, tg, small) ->
if not (newAvailBrFixups.ContainsKey tg) then
failwith ("target "+formatCodeLabel tg+" not found in new fixups")
try
let n = newAvailBrFixups.[tg]
let relOffset = (n - endOfInstr)
if small then
if Bytes.get newCode newFixupLoc <> 0x98 then failwith "br fixupsanity check failed"
newCode.[newFixupLoc] <- b0 relOffset
else
checkFixup32 newCode newFixupLoc 0xf00dd00fl
applyFixup32 newCode newFixupLoc relOffset
with :? KeyNotFoundException -> ())
match newAvailBrFixups.TryGetValue(tg) with
| true, n ->
let relOffset = n - endOfInstr
if small then
if Bytes.get newCode newFixupLoc <> 0x98 then failwith "br fixupsanity check failed"
newCode.[newFixupLoc] <- b0 relOffset
else
checkFixup32 newCode newFixupLoc 0xf00dd00fl
applyFixup32 newCode newFixupLoc relOffset
| _ -> failwith ("target " + formatCodeLabel tg + " not found in new fixups"))
newCode, newReqdStringFixups, newExnClauses, newSeqPoints, newScopes
......@@ -2162,14 +2161,19 @@ module Codebuf =
// Build a table mapping Abstract IL pcs to positions in the generated code buffer
let pc2pos = Array.zeroCreate (instrs.Length+1)
let pc2labs = Dictionary()
for (KeyValue(lab, pc)) in code.Labels do
if pc2labs.ContainsKey pc then pc2labs.[pc] <- lab :: pc2labs.[pc] else pc2labs.[pc] <- [lab]
for KeyValue (lab, pc) in code.Labels do
match pc2labs.TryGetValue(pc) with
| true, labels ->
pc2labs.[pc] <- lab :: labels
| _ -> pc2labs.[pc] <- [lab]
// Emit the instructions
for pc = 0 to instrs.Length do
if pc2labs.ContainsKey pc then
for lab in pc2labs.[pc] do
codebuf.RecordAvailBrFixup lab
match pc2labs.TryGetValue(pc) with
| true, labels ->
for lab in labels do
codebuf.RecordAvailBrFixup(lab)
| _ -> ()
pc2pos.[pc] <- codebuf.code.Position
if pc < instrs.Length then
match instrs.[pc] with
......
......@@ -1199,16 +1199,8 @@ module internal ExtensionTyping =
staticParameters |> Array.map (fun sp ->
let typeBeforeArgumentsName = typeBeforeArguments.PUntaint ((fun st -> st.Name), m)
let spName = sp.PUntaint ((fun sp -> sp.Name), m)
if not (argSpecsTable.ContainsKey spName) then
if sp.PUntaint ((fun sp -> sp.IsOptional), m) then
match sp.PUntaint((fun sp -> sp.RawDefaultValue), m) with
| null -> error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, typeBeforeArgumentsName, typeBeforeArgumentsName, spName), range0))
| v -> v
else
error(Error(FSComp.SR.etProvidedTypeReferenceMissingArgument(spName), range0))
else
let arg = argSpecsTable.[spName]
match argSpecsTable.TryGetValue(spName) with
| true, arg ->
/// Find the name of the representation type for the static parameter
let spReprTypeName =
sp.PUntaint((fun sp ->
......@@ -1232,7 +1224,16 @@ module internal ExtensionTyping =
| "System.Char" -> box (char arg)
| "System.Boolean" -> box (arg = "True")
| "System.String" -> box (string arg)
| s -> error(Error(FSComp.SR.etUnknownStaticArgumentKind(s, typeLogicalName), range0)))
| s -> error(Error(FSComp.SR.etUnknownStaticArgumentKind(s, typeLogicalName), range0))
| _ ->
if sp.PUntaint ((fun sp -> sp.IsOptional), m) then
match sp.PUntaint((fun sp -> sp.RawDefaultValue), m) with
| null -> error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, typeBeforeArgumentsName, typeBeforeArgumentsName, spName), range0))
| v -> v
else
error(Error(FSComp.SR.etProvidedTypeReferenceMissingArgument(spName), range0)))
match TryApplyProvidedType(typeBeforeArguments, None, staticArgs, range0) with
| Some (typeWithArguments, checkTypeName) ->
......
......@@ -1053,10 +1053,10 @@ type PropKey = PropKey of string * ILTypes * ILThisConvention
let AddPropertyDefToHash (m:range) (ht:Dictionary<PropKey,(int * ILPropertyDef)>) (pdef: ILPropertyDef) =
let nm = PropKey(pdef.Name, pdef.Args, pdef.CallingConv)
if ht.ContainsKey nm then
let idx,pd = ht.[nm]
match ht.TryGetValue(nm) with
| true, (idx, pd) ->
ht.[nm] <- (idx, MergePropertyPair m pd pdef)
else
| _ ->
ht.[nm] <- (ht.Count, pdef)
......@@ -1291,10 +1291,9 @@ type CodeGenBuffer(m:range,
let rec lab2pc n lbl =
if n = System.Int32.MaxValue then error(InternalError("recursive label graph",m))
if codeLabelToCodeLabel.ContainsKey lbl then
lab2pc (n+1) codeLabelToCodeLabel.[lbl]
else
codeLabelToPC.[lbl]
match codeLabelToCodeLabel.TryGetValue(lbl) with
| true, l -> lab2pc (n + 1) l
| _ -> codeLabelToPC.[lbl]
let mutable lastSeqPoint = None
......
......@@ -102,17 +102,16 @@ type PropertyCollector(g, amap, m, typ, optFilter, ad) =
let props = new Dictionary<PropInfo,PropInfo>(hashIdentity)
let add pinfo =
if props.ContainsKey(pinfo) then
match props.[pinfo], pinfo with
| FSProp (_,typ,Some vref1,_), FSProp (_,_,_,Some vref2)
| FSProp (_,typ,_,Some vref2), FSProp (_,_,Some vref1,_) ->
let pinfo = FSProp (g,typ,Some vref1,Some vref2)
props.[pinfo] <- pinfo
| _ ->
// This assert fires while editing bad code. We will give a warning later in check.fs
//assert ("unexpected case"= "")
()
else
match props.TryGetValue(pinfo), pinfo with
| (true, FSProp (_, typ, Some vref1 ,_)), FSProp (_, _, _, Some vref2)
| (true, FSProp (_, typ, _, Some vref2)), FSProp (_, _, Some vref1, _) ->
let pinfo = FSProp (g,typ,Some vref1,Some vref2)
props.[pinfo] <- pinfo
| (true, _), _ ->
// This assert fires while editing bad code. We will give a warning later in check.fs
//assert ("unexpected case"= "")
()
| _ ->
props.[pinfo] <- pinfo
member x.Collect(membInfo:ValMemberInfo,vref:ValRef) =
......
......@@ -1162,10 +1162,11 @@ module ProvidedMethodCalls =
// sub in the appropriate argument
// REVIEW: "thisArg" pointer should be first, if present
let vRaw = pe.PUntaint(id,m)
if not (varConv.ContainsKey vRaw) then
let typeProviderDesignation = ExtensionTyping.DisplayNameOfTypeProvider (pe.TypeProvider, m)
error(NumberedError(FSComp.SR.etIncorrectParameterExpression(typeProviderDesignation,vRaw.Name), m))
varConv.[vRaw]
match varConv.TryGetValue(vRaw) with
| true, v -> v
| _ ->
let typeProviderDesignation = ExtensionTyping.DisplayNameOfTypeProvider (pe.TypeProvider, m)
error(NumberedError(FSComp.SR.etIncorrectParameterExpression(typeProviderDesignation,vRaw.Name), m))
and exprToExpr expr =
let _, (resExpr, _) = exprToExprAndWitness false expr
......
......@@ -1412,8 +1412,10 @@ let CheckEntityDefn cenv env (tycon:Entity) =
let immediateProps = GetImmediateIntrinsicPropInfosOfType (None,AccessibleFromSomewhere) cenv.g cenv.amap m typ
let getHash (hash:Dictionary<string,_>) nm =
if hash.ContainsKey(nm) then hash.[nm] else []
let getHash (hash:Dictionary<string,_>) nm =
match hash.TryGetValue(nm) with
| true, h -> h
| _ -> []
// precompute methods grouped by MethInfo.LogicalName
let hashOfImmediateMeths =
......
......@@ -124,13 +124,13 @@ let IsSecurityAttribute (g: TcGlobals) amap (casmap : Dictionary<Stamp, bool>) (
| Some attr ->
match attr.TyconRef.TryDeref with
| VSome _ ->
let tcs = tcref.Stamp
if casmap.ContainsKey(tcs) then
casmap.[tcs]
else
let exists = ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkAppTy attr.TyconRef [])) g amap m AllowMultiIntfInstantiations.Yes (mkAppTy tcref [])
casmap.[tcs] <- exists
exists
let tcs = tcref.Stamp
match casmap.TryGetValue(tcs) with
| true, c -> c
| _ ->
let exists = ExistsInEntireHierarchyOfType (fun t -> typeEquiv g t (mkAppTy attr.TyconRef [])) g amap m AllowMultiIntfInstantiations.Yes (mkAppTy tcref [])
casmap.[tcs] <- exists
exists
| VNone -> false
let IsSecurityCriticalAttribute g (Attrib(tcref, _, _, _, _, _, _)) =
......
......@@ -2190,9 +2190,14 @@ type IParseState with
member internal x.SynArgNameGenerator =
let key = "SynArgNameGenerator"
let bls = x.LexBuffer.BufferLocalStore
if not (bls.ContainsKey key) then
bls.[key] <- box (SynArgNameGenerator())
bls.[key] :?> SynArgNameGenerator
let gen =
match bls.TryGetValue(key) with
| true, gen -> gen
| _ ->
let gen = box (SynArgNameGenerator())
bls.[key] <- gen
gen
gen :?> SynArgNameGenerator
/// Reset the generator used for compiler-generated argument names.
member internal x.ResetSynArgNameGenerator() = x.SynArgNameGenerator.Reset()
......@@ -2208,18 +2213,25 @@ module LexbufLocalXmlDocStore =
lexbuf.BufferLocalStore.[xmlDocKey] <- box (XmlDocCollector())
/// Called from the lexer to save a single line of XML doc comment.
let internal SaveXmlDocLine (lexbuf:Lexbuf, lineText, pos) =
if not (lexbuf.BufferLocalStore.ContainsKey(xmlDocKey)) then
lexbuf.BufferLocalStore.[xmlDocKey] <- box (XmlDocCollector())
let collector = unbox<XmlDocCollector>(lexbuf.BufferLocalStore.[xmlDocKey])
collector.AddXmlDocLine (lineText, pos)
let internal SaveXmlDocLine (lexbuf:Lexbuf, lineText, pos) =
let collector =
match lexbuf.BufferLocalStore.TryGetValue(xmlDocKey) with
| true, collector -> collector
| _ ->
let collector = box (XmlDocCollector())
lexbuf.BufferLocalStore.[xmlDocKey] <- collector
collector
let collector = unbox<XmlDocCollector>(collector)
collector.AddXmlDocLine(lineText, pos)
/// Called from the parser each time we parse a construct that marks the end of an XML doc comment range,
/// e.g. a 'type' declaration. The markerRange is the range of the keyword that delimits the construct.
let internal GrabXmlDocBeforeMarker (lexbuf:Lexbuf, markerRange:range) =
if lexbuf.BufferLocalStore.ContainsKey(xmlDocKey) then
PreXmlDoc.CreateFromGrabPoint(unbox<XmlDocCollector>(lexbuf.BufferLocalStore.[xmlDocKey]),markerRange.End)
else
let internal GrabXmlDocBeforeMarker (lexbuf:Lexbuf, markerRange:range) =
match lexbuf.BufferLocalStore.TryGetValue(xmlDocKey) with
| true, collector ->
let collector = unbox<XmlDocCollector>(collector)
PreXmlDoc.CreateFromGrabPoint(collector, markerRange.End)
| _ ->
PreXmlDoc.Empty
......@@ -2239,9 +2251,12 @@ type NiceNameGenerator() =
member x.FreshCompilerGeneratedName (name,m:range) =
lock lockObj (fun () ->
let basicName = GetBasicNameOfPossibleCompilerGeneratedName name
let n = (if basicNameCounts.ContainsKey basicName then basicNameCounts.[basicName] else 0)
let n =
match basicNameCounts.TryGetValue(basicName) with
| true, count -> count
| _ -> 0
let nm = CompilerGeneratedNameSuffix basicName (string m.StartLine + (match n with 0 -> "" | n -> "-" + string n))
basicNameCounts.[basicName] <- n+1
basicNameCounts.[basicName] <- n + 1
nm)
member x.Reset () =
......@@ -2265,17 +2280,21 @@ type StableNiceNameGenerator() =
let basicNameCounts = new Dictionary<string,int>(100)
member x.GetUniqueCompilerGeneratedName (name,m:range,uniq) =
lock lockObj (fun () ->
let basicName = GetBasicNameOfPossibleCompilerGeneratedName name
if names.ContainsKey (basicName,uniq) then
names.[(basicName,uniq)]
else
let n = (if basicNameCounts.ContainsKey basicName then basicNameCounts.[basicName] else 0)
let nm = CompilerGeneratedNameSuffix basicName (string m.StartLine + (match n with 0 -> "" | n -> "-" + string n))
names.[(basicName,uniq)] <- nm
basicNameCounts.[basicName] <- n+1
nm
)
lock lockObj (fun () ->
let basicName = GetBasicNameOfPossibleCompilerGeneratedName name
let key = basicName, uniq
match names.TryGetValue(key) with
| true, nm -> nm
| _ ->
let n =
match basicNameCounts.TryGetValue(basicName) with
| true, c -> c
| _ -> 0
let nm = CompilerGeneratedNameSuffix basicName (string m.StartLine + (match n with 0 -> "" | n -> "-" + string n))
names.[key] <- nm
basicNameCounts.[basicName] <- n + 1
nm
)
member x.Reset () =
lock lockObj (fun () ->
......
......@@ -1433,8 +1433,8 @@ module StaticLinker =
let generatedILTypeDefs =
let rec buildRelocatedGeneratedType (ProviderGeneratedType(ilOrigTyRef, ilTgtTyRef, ch)) =
let isNested = not (isNil ilTgtTyRef.Enclosing)
if allTypeDefsInProviderGeneratedAssemblies.ContainsKey ilOrigTyRef then
let ilOrigTypeDef = allTypeDefsInProviderGeneratedAssemblies.[ilOrigTyRef]
match allTypeDefsInProviderGeneratedAssemblies.TryGetValue(ilOrigTyRef) with
| true, ilOrigTypeDef ->
if debugStaticLinking then printfn "Relocating %s to %s " ilOrigTyRef.QualifiedName ilTgtTyRef.QualifiedName
let ilOrigTypeDef =
if isNested then
......@@ -1446,7 +1446,7 @@ module StaticLinker =
else ilOrigTypeDef
ilOrigTypeDef.With(name = ilTgtTyRef.Name,
nestedTypes = mkILTypeDefs (List.map buildRelocatedGeneratedType ch))
else
| _ ->
// If there is no matching IL type definition, then make a simple container class
if debugStaticLinking then printfn "Generating simple class '%s' because we didn't find an original type '%s' in a provider generated assembly" ilTgtTyRef.QualifiedName ilOrigTyRef.QualifiedName
mkILSimpleClass ilGlobals (ilTgtTyRef.Name, (if isNested then ILTypeDefAccess.Nested ILMemberAccess.Public else ILTypeDefAccess.Public), emptyILMethods, emptyILFields, mkILTypeDefs (List.map buildRelocatedGeneratedType ch) , emptyILProperties, emptyILEvents, emptyILCustomAttrs, ILTypeInit.OnAny)
......
......@@ -134,9 +134,9 @@ let ImportILTypeRefUncached (env:ImportMap) m (tref:ILTypeRef) =
/// Import a reference to a type definition, given an AbstractIL ILTypeRef, with caching
let ImportILTypeRef (env:ImportMap) m (tref:ILTypeRef) =
if env.ILTypeRefToTyconRefCache.ContainsKey(tref) then
env.ILTypeRefToTyconRefCache.[tref]
else
match env.ILTypeRefToTyconRefCache.TryGetValue(tref) with
| true, tcref -> tcref
| _ ->
let tcref = ImportILTypeRefUncached env m tref
env.ILTypeRefToTyconRefCache.[tref] <- tcref
tcref
......@@ -430,8 +430,11 @@ let multisetDiscriminateAndMap nodef tipf (items: ('Key list * 'Value) list) =
for (keylist,v) in items do
match keylist with
| [] -> ()
| key::rest ->
buckets.[key] <- (rest,v) :: (if buckets.ContainsKey key then buckets.[key] else [])
| key :: rest ->
buckets.[key] <-
match buckets.TryGetValue(key) with
| true, b -> (rest,v) :: b
| _ -> (rest,v) :: []
[ for (KeyValue(key,items)) in buckets -> nodef key items ]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册