From 014798da81501b60b46958e8edae342365698cde Mon Sep 17 00:00:00 2001 From: Will Smith Date: Wed, 21 Oct 2020 12:34:29 -0700 Subject: [PATCH 1/5] Making several uses of Dictionary types be ConcurrentDictionary --- src/absil/il.fs | 3 ++- src/absil/illib.fs | 17 ++++++++++------- src/absil/ilread.fs | 4 ++-- src/fsharp/CompilerConfig.fs | 5 +++-- src/fsharp/ExtensionTyping.fs | 1 + src/fsharp/ExtensionTyping.fsi | 2 +- src/fsharp/IlxGen.fs | 3 +++ src/fsharp/InfoReader.fs | 3 ++- src/fsharp/Optimizer.fs | 3 ++- src/fsharp/TcGlobals.fs | 5 +++-- src/fsharp/lexhelp.fs | 2 +- 11 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 19e0d3c1053..c481356bc15 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -12,6 +12,7 @@ open System.IO open System.Collections open System.Collections.Generic open System.Collections.Concurrent +open System.Collections.ObjectModel open System.Reflection open System.Text open System.Threading @@ -2130,7 +2131,7 @@ and [] ILTypeDefs(f : unit -> ILPreTypeDef[]) = for pre in arr do let key = pre.Namespace, pre.Name t.[key] <- pre - t) + ReadOnlyDictionary t) member x.AsArray = [| for pre in array.Value -> pre.GetTypeDef() |] diff --git a/src/absil/illib.fs b/src/absil/illib.fs index 90709ee6cc7..da10b5eea94 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -6,6 +6,7 @@ module public FSharp.Compiler.AbstractIL.Internal.Library open System open System.Collections.Generic +open System.Collections.Concurrent open System.Diagnostics open System.IO open System.Reflection @@ -959,16 +960,18 @@ let _ = eventually { use x = null in return 1 } /// Generates unique stamps type UniqueStampGenerator<'T when 'T : equality>() = - let encodeTab = new Dictionary<'T, int>(HashIdentity.Structural) + let gate = obj () + let encodeTab = new ConcurrentDictionary<'T, int>(HashIdentity.Structural) let mutable nItems = 0 let encode str = match encodeTab.TryGetValue str with | true, idx -> idx | _ -> - let idx = nItems - encodeTab.[str] <- idx - nItems <- nItems + 1 - idx + lock gate (fun () -> + let idx = nItems + encodeTab.[str] <- idx + nItems <- nItems + 1 + idx) member this.Encode str = encode str @@ -977,7 +980,7 @@ type UniqueStampGenerator<'T when 'T : equality>() = /// memoize tables (all entries cached, never collected) type MemoizationTable<'T, 'U>(compute: 'T -> 'U, keyComparer: IEqualityComparer<'T>, ?canMemoize) = - let table = new Dictionary<'T, 'U>(keyComparer) + let table = new ConcurrentDictionary<'T, 'U>(keyComparer) member t.Apply x = if (match canMemoize with None -> true | Some f -> f x) then @@ -1066,7 +1069,7 @@ type LazyWithContext<'T, 'ctxt> = /// Intern tables to save space. module Tables = let memoize f = - let t = new Dictionary<_, _>(1000, HashIdentity.Structural) + let t = new ConcurrentDictionary<_, _>(Environment.ProcessorCount, 1000, HashIdentity.Structural) fun x -> match t.TryGetValue x with | true, res -> res diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index 841c7354fc4..d7470c9d39a 100644 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -697,7 +697,7 @@ let mkCacheInt32 lowMem _inbase _nm _sz = fun f (idx: int32) -> let cache = match !cache with - | null -> cache := new Dictionary(11) + | null -> cache := new ConcurrentDictionary(Environment.ProcessorCount, 11) | _ -> () !cache match cache.TryGetValue idx with @@ -719,7 +719,7 @@ let mkCacheGeneric lowMem _inbase _nm _sz = fun f (idx :'T) -> let cache = match !cache with - | null -> cache := new Dictionary<_, _>(11 (* sz: int *) ) + | null -> cache := new ConcurrentDictionary<_, _>(Environment.ProcessorCount, 11 (* sz: int *) ) | _ -> () !cache match cache.TryGetValue idx with diff --git a/src/fsharp/CompilerConfig.fs b/src/fsharp/CompilerConfig.fs index 060d3f864cc..e36ec359151 100644 --- a/src/fsharp/CompilerConfig.fs +++ b/src/fsharp/CompilerConfig.fs @@ -5,6 +5,7 @@ module internal FSharp.Compiler.CompilerConfig open System open System.Collections.Generic +open System.Collections.Concurrent open System.Diagnostics open System.IO open System.Text @@ -177,8 +178,8 @@ type IRawFSharpAssemblyData = /// Cache of time stamps as we traverse a project description type TimeStampCache(defaultTimeStamp: DateTime) = - let files = Dictionary() - let projects = Dictionary(HashIdentity.Reference) + let files = ConcurrentDictionary() + let projects = ConcurrentDictionary(HashIdentity.Reference) member cache.GetFileTimeStamp fileName = let ok, v = files.TryGetValue fileName if ok then v else diff --git a/src/fsharp/ExtensionTyping.fs b/src/fsharp/ExtensionTyping.fs index 9a064ae17a0..289f7221299 100644 --- a/src/fsharp/ExtensionTyping.fs +++ b/src/fsharp/ExtensionTyping.fs @@ -267,6 +267,7 @@ module internal ExtensionTyping = /// appears that the laziness likely serves no purpose and could be safely removed. and ProvidedTypeContext = | NoEntries + // The dictionaries are safe because the ProvidedType with the ProvidedTypeContext are only accessed one thread at a time during type-checking. | Entries of Dictionary * Lazy> static member Empty = NoEntries diff --git a/src/fsharp/ExtensionTyping.fsi b/src/fsharp/ExtensionTyping.fsi index 00ffbf1058e..e8ba60842a5 100755 --- a/src/fsharp/ExtensionTyping.fsi +++ b/src/fsharp/ExtensionTyping.fsi @@ -65,7 +65,7 @@ module internal ExtensionTyping = /// /// At the moment this is the "Type --> ILTypeRef" and "Type --> Tycon" remapping /// context for generated types (it is empty for erased types). This is computed from - /// while processing the [] declaration related to the type. + /// while processing the [] declaration related to the type. /// /// Immutable (after type generation for a [] declaration populates the dictionaries). /// diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 54d959fb13e..0c75084f81b 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -1446,6 +1446,7 @@ and TypeDefsBuilder() = tdefs.Add (tdef.Name, (idx, (new TypeDefBuilder(tdef, tdefDiscards), eliminateIfEmpty))) type AnonTypeGenerationTable() = + // Dictionary is safe here as it will only be used during the codegen stage - will happen on a single thread. let dict = Dictionary(HashIdentity.Structural) member __.Table = dict @@ -1456,6 +1457,7 @@ type AssemblyBuilder(cenv: cenv, anonTypeTable: AnonTypeGenerationTable) as mgbu let gtdefs= new TypeDefsBuilder() // The definitions of top level values, as quotations. + // Dictionary is safe here as it will only be used during the codegen stage - will happen on a single thread. let mutable reflectedDefinitions: Dictionary = Dictionary(HashIdentity.Reference) let mutable extraBindingsToGenerate = [] @@ -8170,6 +8172,7 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal: Constrai // The incremental state held by the ILX code generator let mutable ilxGenEnv = GetEmptyIlxGenEnv tcGlobals ccu let anonTypeTable = AnonTypeGenerationTable() + // Dictionaries are safe here as they will only be used during the codegen stage - will happen on a single thread. let intraAssemblyInfo = { StaticFieldInfo = new Dictionary<_, _>(HashIdentity.Structural) } let casApplied = new Dictionary() diff --git a/src/fsharp/InfoReader.fs b/src/fsharp/InfoReader.fs index 419f357ed95..fd44eeb4b29 100644 --- a/src/fsharp/InfoReader.fs +++ b/src/fsharp/InfoReader.fs @@ -6,6 +6,7 @@ module internal FSharp.Compiler.InfoReader open System open System.Collections.Generic +open System.Collections.Concurrent open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL @@ -107,7 +108,7 @@ type PropertyCollector(g, amap, m, ty, optFilter, ad) = PropInfosEquivByNameAndPartialSig EraseNone g amap m pinfo1 pinfo2 && pinfo1.IsDefiniteFSharpOverride = pinfo2.IsDefiniteFSharpOverride ) - let props = new Dictionary(hashIdentity) + let props = new ConcurrentDictionary(hashIdentity) let add pinfo = match props.TryGetValue pinfo, pinfo with diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 9408e49e588..c7ddb417a6b 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -32,6 +32,7 @@ open FSharp.Compiler.TcGlobals open FSharp.Compiler.TypeRelations open System.Collections.Generic +open System.Collections.ObjectModel #if DEBUG let verboseOptimizationInfo = @@ -162,7 +163,7 @@ type ValInfos(entries) = if dict.ContainsKey vkey then failwithf "dictionary already contains key %A" vkey dict.Add(vkey, p) |> ignore - dict), id) + ReadOnlyDictionary dict), id) member x.Entries = valInfoTable.Force().Values diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index fe67f07ade0..d2b66a921fb 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -9,6 +9,7 @@ module internal FSharp.Compiler.TcGlobals open System.Collections.Generic +open System.Collections.Concurrent open System.Diagnostics open FSharp.Compiler.AbstractIL @@ -360,7 +361,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let mkForallTyIfNeeded d r = match d with [] -> r | tps -> TType_forall(tps, r) // A table of all intrinsics that the compiler cares about - let v_knownIntrinsics = Dictionary<(string * string option * string * int), ValRef>(HashIdentity.Structural) + let v_knownIntrinsics = ConcurrentDictionary<(string * string option * string * int), ValRef>(HashIdentity.Structural) let makeIntrinsicValRefGeneral isKnown (enclosingEntity, logicalName, memberParentName, compiledNameOpt, typars, (argtys, rty)) = let ty = mkForallTyIfNeeded typars (mkIteratedFunTy (List.map mkSmallRefTupledTy argtys) rty) @@ -374,7 +375,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let key = (enclosingEntity.LastItemMangledName, memberParentName, compiledName, argCount) assert not (v_knownIntrinsics.ContainsKey(key)) if isKnown && not (v_knownIntrinsics.ContainsKey(key)) then - v_knownIntrinsics.Add(key, ValRefForIntrinsic vref) + v_knownIntrinsics.[key] <- ValRefForIntrinsic vref vref let makeIntrinsicValRef info = makeIntrinsicValRefGeneral true info diff --git a/src/fsharp/lexhelp.fs b/src/fsharp/lexhelp.fs index 26a50de6f28..a205e5f5ddd 100644 --- a/src/fsharp/lexhelp.fs +++ b/src/fsharp/lexhelp.fs @@ -39,7 +39,7 @@ type LightSyntaxStatus(initial:bool,warn:bool) = /// Manage lexer resources (string interning) [] type LexResourceManager(?capacity: int) = - let strings = new System.Collections.Generic.Dictionary(defaultArg capacity 1024) + let strings = new System.Collections.Concurrent.ConcurrentDictionary(Environment.ProcessorCount, defaultArg capacity 1024) member x.InternIdentifierToken(s) = match strings.TryGetValue s with | true, res -> res From 5eb80924ed1099034cb6f8c90309d08d1e583b78 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Wed, 21 Oct 2020 12:37:24 -0700 Subject: [PATCH 2/5] Remove space --- src/fsharp/ExtensionTyping.fsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/ExtensionTyping.fsi b/src/fsharp/ExtensionTyping.fsi index e8ba60842a5..00ffbf1058e 100755 --- a/src/fsharp/ExtensionTyping.fsi +++ b/src/fsharp/ExtensionTyping.fsi @@ -65,7 +65,7 @@ module internal ExtensionTyping = /// /// At the moment this is the "Type --> ILTypeRef" and "Type --> Tycon" remapping /// context for generated types (it is empty for erased types). This is computed from - /// while processing the [] declaration related to the type. + /// while processing the [] declaration related to the type. /// /// Immutable (after type generation for a [] declaration populates the dictionaries). /// From 785f4b4d256afb8d0f1085be5f7ef9103e1bc628 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Thu, 22 Oct 2020 13:57:23 -0700 Subject: [PATCH 3/5] Fixing tests --- .../SurfaceArea.netstandard.fs | 4 +- tests/service/ProjectAnalysisTests.fs | 240 +++++++++--------- 2 files changed, 126 insertions(+), 118 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs index e4a89018279..f5eebfdae42 100644 --- a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs +++ b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs @@ -18369,8 +18369,8 @@ FSharp.Compiler.AbstractIL.Internal.Library+UndefinedException: Int32 GetHashCod FSharp.Compiler.AbstractIL.Internal.Library+UndefinedException: Int32 GetHashCode(System.Collections.IEqualityComparer) FSharp.Compiler.AbstractIL.Internal.Library+UndefinedException: Void .ctor() FSharp.Compiler.AbstractIL.Internal.Library+UniqueStampGenerator`1[T]: Int32 Encode(T) -FSharp.Compiler.AbstractIL.Internal.Library+UniqueStampGenerator`1[T]: KeyCollection Table -FSharp.Compiler.AbstractIL.Internal.Library+UniqueStampGenerator`1[T]: KeyCollection get_Table() +FSharp.Compiler.AbstractIL.Internal.Library+UniqueStampGenerator`1[T]: System.Collections.Generic.ICollection`1[T] Table +FSharp.Compiler.AbstractIL.Internal.Library+UniqueStampGenerator`1[T]: System.Collections.Generic.ICollection`1[T] get_Table() FSharp.Compiler.AbstractIL.Internal.Library+UniqueStampGenerator`1[T]: Void .ctor() FSharp.Compiler.AbstractIL.Internal.Library+ValueOptionInternal: Microsoft.FSharp.Core.FSharpValueOption`1[a] ofOption[a](Microsoft.FSharp.Core.FSharpOption`1[a]) FSharp.Compiler.AbstractIL.Internal.Library+ValueOptionInternal: Microsoft.FSharp.Core.FSharpValueOption`1[b] bind[a,b](Microsoft.FSharp.Core.FSharpFunc`2[a,Microsoft.FSharp.Core.FSharpValueOption`1[b]], Microsoft.FSharp.Core.FSharpValueOption`1[a]) diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index 9122d855425..4f35e6b1ebd 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -945,81 +945,84 @@ let ``Test project3 all symbols in signature`` () = let wholeProjectResults = checker.ParseAndCheckProject(Project3.options) |> Async.RunSynchronously let allSymbols = allSymbolsInEntities false wholeProjectResults.AssemblySignature.Entities - [ for x in allSymbols -> x.ToString(), attribsOfSymbol x ] - |> shouldEqual - [("M", ["module"]); - ("val IFooImplObjectExpression", ["val"]); - ("val CFooImplObjectExpression", ["val"]); - ("val getP", ["val"]); - ("val setP", ["val"]); ("val getE", ["val"]); - ("val getM", ["val"]); - ("IFoo", ["interface"]); - ("member InterfaceMethod", ["slot"; "member"]); - ("member add_InterfaceEvent", ["slot"; "member"; "add"]); - ("member get_InterfaceEvent", ["slot"; "member"; "getter"]); - ("member get_InterfaceProperty", ["slot"; "member"; "getter"]); - ("member remove_InterfaceEvent", ["slot"; "member"; "remove"]); - ("member set_InterfacePropertySet", ["slot"; "member"; "setter"]); - ("property InterfacePropertySet", ["slot"; "member"; "prop"]); - ("property InterfaceProperty", ["slot"; "member"; "prop"]); - ("property InterfaceEvent", ["slot"; "member"; "prop"; "clievent"]); - ("CFoo", ["class"]); - ("member .ctor", ["member"; "ctor"]); - ("member AbstractClassMethod", ["slot"; "member"]); - ("member add_AbstractClassEvent", ["slot"; "member"; "add"]); - ("member get_AbstractClassEvent", ["slot"; "member"; "getter"]); - ("member get_AbstractClassProperty", ["slot"; "member"; "getter"]); - ("member remove_AbstractClassEvent", ["slot"; "member"; "remove"]); - ("member set_AbstractClassPropertySet", ["slot"; "member"; "setter"]); - ("property AbstractClassPropertySet", ["slot"; "member"; "prop"]); - ("property AbstractClassProperty", ["slot"; "member"; "prop"]); - ("property AbstractClassEvent", ["slot"; "member"; "prop"; "clievent"]); - ("CBaseFoo", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member BaseClassMethod", ["slot"; "member"]); - ("member BaseClassMethod", ["member"; "overridemem"]); - ("member add_BaseClassEvent", ["slot"; "member"; "add"]); - ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); - ("member get_BaseClassEvent", ["slot"; "member"; "getter"]); - ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); - ("member get_BaseClassProperty", ["slot"; "member"; "getter"]); - ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); - ("member remove_BaseClassEvent", ["slot"; "member"; "remove"]); - ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); - ("member set_BaseClassPropertySet", ["slot"; "member"; "setter"]); - ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); - ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); - ("property BaseClassPropertySet", ["slot"; "member"; "prop"]); - ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); - ("property BaseClassProperty", ["slot"; "member"; "prop"]); - ("property BaseClassEvent", ["member"; "prop"; "overridemem"]); - ("property BaseClassEvent", ["slot"; "member"; "prop"]); - ("IFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member InterfaceMethod", ["member"; "overridemem"; "intfmem"]); - ("member add_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); - ("member get_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); - ("member get_InterfaceProperty", ["member"; "overridemem"; "intfmem"]); - ("member remove_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); - ("member set_InterfacePropertySet", ["member"; "overridemem"; "intfmem"]); - ("CFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member AbstractClassMethod", ["member"; "overridemem"]); - ("member add_AbstractClassEvent", ["member"; "add"; "overridemem"]); - ("member get_AbstractClassEvent", ["member"; "getter"; "overridemem"]); - ("member get_AbstractClassProperty", ["member"; "getter"; "overridemem"]); - ("member remove_AbstractClassEvent", ["member"; "remove"; "overridemem"]); - ("member set_AbstractClassPropertySet", ["member"; "setter"; "overridemem"]); - ("property AbstractClassPropertySet", ["member"; "prop"; "overridemem"]); - ("property AbstractClassProperty", ["member"; "prop"; "overridemem"]); - ("property AbstractClassEvent", ["member"; "prop"; "clievent"; "overridemem"]); - ("CBaseFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); - ("member BaseClassMethod", ["member"; "overridemem"]); - ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); - ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); - ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); - ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); - ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); - ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); - ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); - ("property BaseClassEvent", ["member"; "prop"; "clievent"; "overridemem"])] + let results = [ for x in allSymbols -> x.ToString(), attribsOfSymbol x ] + [("M", ["module"]); + ("val IFooImplObjectExpression", ["val"]); + ("val CFooImplObjectExpression", ["val"]); + ("val getP", ["val"]); + ("val setP", ["val"]); ("val getE", ["val"]); + ("val getM", ["val"]); + ("IFoo", ["interface"]); + ("member InterfaceMethod", ["slot"; "member"]); + ("member add_InterfaceEvent", ["slot"; "member"; "add"]); + ("member get_InterfaceEvent", ["slot"; "member"; "getter"]); + ("member get_InterfaceProperty", ["slot"; "member"; "getter"]); + ("member remove_InterfaceEvent", ["slot"; "member"; "remove"]); + ("member set_InterfacePropertySet", ["slot"; "member"; "setter"]); + ("property InterfacePropertySet", ["slot"; "member"; "prop"]); + ("property InterfaceProperty", ["slot"; "member"; "prop"]); + ("property InterfaceEvent", ["slot"; "member"; "prop"; "clievent"]); + ("CFoo", ["class"]); + ("member .ctor", ["member"; "ctor"]); + ("member AbstractClassMethod", ["slot"; "member"]); + ("member add_AbstractClassEvent", ["slot"; "member"; "add"]); + ("member get_AbstractClassEvent", ["slot"; "member"; "getter"]); + ("member get_AbstractClassProperty", ["slot"; "member"; "getter"]); + ("member remove_AbstractClassEvent", ["slot"; "member"; "remove"]); + ("member set_AbstractClassPropertySet", ["slot"; "member"; "setter"]); + ("property AbstractClassPropertySet", ["slot"; "member"; "prop"]); + ("property AbstractClassProperty", ["slot"; "member"; "prop"]); + ("property AbstractClassEvent", ["slot"; "member"; "prop"; "clievent"]); + ("CBaseFoo", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member BaseClassMethod", ["slot"; "member"]); + ("member BaseClassMethod", ["member"; "overridemem"]); + ("member add_BaseClassEvent", ["slot"; "member"; "add"]); + ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); + ("member get_BaseClassEvent", ["slot"; "member"; "getter"]); + ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); + ("member get_BaseClassProperty", ["slot"; "member"; "getter"]); + ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); + ("member remove_BaseClassEvent", ["slot"; "member"; "remove"]); + ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); + ("member set_BaseClassPropertySet", ["slot"; "member"; "setter"]); + ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); + ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); + ("property BaseClassPropertySet", ["slot"; "member"; "prop"]); + ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); + ("property BaseClassProperty", ["slot"; "member"; "prop"]); + ("property BaseClassEvent", ["member"; "prop"; "overridemem"]); + ("property BaseClassEvent", ["slot"; "member"; "prop"]); + ("IFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member InterfaceMethod", ["member"; "overridemem"; "intfmem"]); + ("member add_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); + ("member get_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); + ("member get_InterfaceProperty", ["member"; "overridemem"; "intfmem"]); + ("member remove_InterfaceEvent", ["member"; "overridemem"; "intfmem"]); + ("member set_InterfacePropertySet", ["member"; "overridemem"; "intfmem"]); + ("CFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member AbstractClassMethod", ["member"; "overridemem"]); + ("member add_AbstractClassEvent", ["member"; "add"; "overridemem"]); + ("member get_AbstractClassEvent", ["member"; "getter"; "overridemem"]); + ("member get_AbstractClassProperty", ["member"; "getter"; "overridemem"]); + ("member remove_AbstractClassEvent", ["member"; "remove"; "overridemem"]); + ("member set_AbstractClassPropertySet", ["member"; "setter"; "overridemem"]); + ("property AbstractClassPropertySet", ["member"; "prop"; "overridemem"]); + ("property AbstractClassProperty", ["member"; "prop"; "overridemem"]); + ("property AbstractClassEvent", ["member"; "prop"; "clievent"; "overridemem"]); + ("CBaseFooImpl", ["class"]); ("member .ctor", ["member"; "ctor"]); + ("member BaseClassMethod", ["member"; "overridemem"]); + ("member add_BaseClassEvent", ["member"; "add"; "overridemem"]); + ("member get_BaseClassEvent", ["member"; "getter"; "overridemem"]); + ("member get_BaseClassProperty", ["member"; "getter"; "overridemem"]); + ("member remove_BaseClassEvent", ["member"; "remove"; "overridemem"]); + ("member set_BaseClassPropertySet", ["member"; "setter"; "overridemem"]); + ("property BaseClassPropertySet", ["member"; "prop"; "overridemem"]); + ("property BaseClassProperty", ["member"; "prop"; "overridemem"]); + ("property BaseClassEvent", ["member"; "prop"; "clievent"; "overridemem"])] + |> List.iter (fun x -> + if results |> List.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x + ) [] let ``Test project3 all uses of all signature symbols`` () = @@ -3240,13 +3243,16 @@ let ``Test Project23 property`` () = let classTypeUse = allSymbolsUses |> Array.find (fun su -> su.Symbol.DisplayName = "Class") let classTypeDefn = classTypeUse.Symbol :?> FSharpEntity - [ for x in classTypeDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] - |> shouldEqual - [(".ctor", ["member"; "ctor"]); - ("get_Property", ["member"; "getter"]); - ("get_StaticProperty", ["member"; "getter"]); - ("StaticProperty", ["member"; "prop"]); - ("Property", ["member"; "prop"])] + let results = [ for x in classTypeDefn.MembersFunctionsAndValues -> x.LogicalName, attribsOfSymbol x ] + [(".ctor", ["member"; "ctor"]); + ("get_Property", ["member"; "getter"]); + ("get_StaticProperty", ["member"; "getter"]); + ("StaticProperty", ["member"; "prop"]); + ("Property", ["member"; "prop"])] + |> List.iter (fun x -> + if results |> List.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x + ) let getterModuleUse = allSymbolsUses |> Array.find (fun su -> su.Symbol.DisplayName = "Getter") let getterModuleDefn = getterModuleUse.Symbol :?> FSharpEntity @@ -3957,40 +3963,42 @@ let ``Test project28 all symbols in signature`` () = | _ -> typeName, s.DisplayName, "unknown") |> Seq.toArray - xmlDocSigs - |> shouldEqual - [|("FSharpEntity", "M", "T:M"); - ("FSharpMemberOrFunctionOrValue", "( |Even|Odd| )", "M:M.|Even|Odd|(System.Int32)"); - ("FSharpMemberOrFunctionOrValue", "TestNumber", "M:M.TestNumber(System.Int32)"); - ("FSharpEntity", "DU", "T:M.DU"); - ("FSharpUnionCase", "A", "T:M.DU.A"); - ("FSharpField", "Item", "T:M.DU.A"); - ("FSharpUnionCase", "B", "T:M.DU.B"); - ("FSharpField", "Item", "T:M.DU.B"); - ("FSharpEntity", "XmlDocSigTest", "T:M.XmlDocSigTest"); - ("FSharpMemberOrFunctionOrValue", "( .ctor )", "M:M.XmlDocSigTest.#ctor"); - ("FSharpMemberOrFunctionOrValue", "AMethod", "M:M.XmlDocSigTest.AMethod"); - ("FSharpMemberOrFunctionOrValue", "AnotherMethod", "M:M.XmlDocSigTest.AnotherMethod"); - ("FSharpMemberOrFunctionOrValue", "TestEvent1", "M:M.XmlDocSigTest.TestEvent1(System.Object)"); - ("FSharpMemberOrFunctionOrValue", "TestEvent2", "M:M.XmlDocSigTest.TestEvent2(System.Object)"); - ("FSharpMemberOrFunctionOrValue", "add_AnEvent", "M:M.XmlDocSigTest.add_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); - ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); - ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); - ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); - ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); - ("FSharpMemberOrFunctionOrValue", "remove_AnEvent", "M:M.XmlDocSigTest.remove_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); - ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); - ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); - ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); - ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); - ("FSharpField", "event1", "P:M.XmlDocSigTest.event1"); - ("FSharpField", "event2", "P:M.XmlDocSigTest.event2"); - ("FSharpField", "aString", "P:M.XmlDocSigTest.aString"); - ("FSharpField", "anInt", "P:M.XmlDocSigTest.anInt"); - ("FSharpEntity", "Use", "T:M.Use"); - ("FSharpMemberOrFunctionOrValue", "( .ctor )", "M:M.Use.#ctor"); - ("FSharpMemberOrFunctionOrValue", "Test", "M:M.Use.Test``1(``0)"); - ("FSharpGenericParameter", "?", "")|] + [|("FSharpEntity", "M", "T:M"); + ("FSharpMemberOrFunctionOrValue", "( |Even|Odd| )", "M:M.|Even|Odd|(System.Int32)"); + ("FSharpMemberOrFunctionOrValue", "TestNumber", "M:M.TestNumber(System.Int32)"); + ("FSharpEntity", "DU", "T:M.DU"); + ("FSharpUnionCase", "A", "T:M.DU.A"); + ("FSharpField", "Item", "T:M.DU.A"); + ("FSharpUnionCase", "B", "T:M.DU.B"); + ("FSharpField", "Item", "T:M.DU.B"); + ("FSharpEntity", "XmlDocSigTest", "T:M.XmlDocSigTest"); + ("FSharpMemberOrFunctionOrValue", "( .ctor )", "M:M.XmlDocSigTest.#ctor"); + ("FSharpMemberOrFunctionOrValue", "AMethod", "M:M.XmlDocSigTest.AMethod"); + ("FSharpMemberOrFunctionOrValue", "AnotherMethod", "M:M.XmlDocSigTest.AnotherMethod"); + ("FSharpMemberOrFunctionOrValue", "TestEvent1", "M:M.XmlDocSigTest.TestEvent1(System.Object)"); + ("FSharpMemberOrFunctionOrValue", "TestEvent2", "M:M.XmlDocSigTest.TestEvent2(System.Object)"); + ("FSharpMemberOrFunctionOrValue", "add_AnEvent", "M:M.XmlDocSigTest.add_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); + ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); + ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); + ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); + ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); + ("FSharpMemberOrFunctionOrValue", "remove_AnEvent", "M:M.XmlDocSigTest.remove_AnEvent(Microsoft.FSharp.Control.FSharpHandler{System.Tuple{M.XmlDocSigTest,System.Object}})"); + ("FSharpMemberOrFunctionOrValue", "AnotherProperty", "P:M.XmlDocSigTest.AnotherProperty"); + ("FSharpMemberOrFunctionOrValue", "AnotherEvent", "P:M.XmlDocSigTest.AnotherEvent"); + ("FSharpMemberOrFunctionOrValue", "AnEvent", "P:M.XmlDocSigTest.AnEvent"); + ("FSharpMemberOrFunctionOrValue", "AProperty", "P:M.XmlDocSigTest.AProperty"); + ("FSharpField", "event1", "P:M.XmlDocSigTest.event1"); + ("FSharpField", "event2", "P:M.XmlDocSigTest.event2"); + ("FSharpField", "aString", "P:M.XmlDocSigTest.aString"); + ("FSharpField", "anInt", "P:M.XmlDocSigTest.anInt"); + ("FSharpEntity", "Use", "T:M.Use"); + ("FSharpMemberOrFunctionOrValue", "( .ctor )", "M:M.Use.#ctor"); + ("FSharpMemberOrFunctionOrValue", "Test", "M:M.Use.Test``1(``0)"); + ("FSharpGenericParameter", "?", "")|] + |> Array.iter (fun x -> + if xmlDocSigs |> Array.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x + ) #endif module internal Project29 = From 93c05ea51e6bde0745e6d2a0a06d6befd7230f7b Mon Sep 17 00:00:00 2001 From: Will Smith Date: Fri, 23 Oct 2020 13:03:19 -0700 Subject: [PATCH 4/5] Fixing tests --- tests/service/ProjectAnalysisTests.fs | 47 +++++++++++++++------------ 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index 4f35e6b1ebd..24c44e12c40 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -4864,28 +4864,33 @@ let ``Test project38 abstract slot information`` () = "type " + printType s.DeclaringType + tgen + " with member " + s.Name + mgen + " : " + args + " -> " + printType s.AbstractReturnType - let a2ent = wholeProjectResults.AssemblySignature.Entities |> Seq.find (fun e -> e.FullName = "OverrideTests.A`2") - a2ent.MembersFunctionsAndValues |> Seq.map (fun m -> - m.CompiledName, (m.ImplementedAbstractSignatures |> Seq.map printAbstractSignature |> List.ofSeq) + let results = + let a2ent = wholeProjectResults.AssemblySignature.Entities |> Seq.find (fun e -> e.FullName = "OverrideTests.A`2") + a2ent.MembersFunctionsAndValues |> Seq.map (fun m -> + m.CompiledName, (m.ImplementedAbstractSignatures |> Seq.map printAbstractSignature |> List.ofSeq) + ) + |> Array.ofSeq + + [| + ".ctor", [] + "Generic", ["type OverrideTests.B<'YY> original generics: <'Y> with member Generic : 'Y -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic : named:'X -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic<'Y> : 'X * 'Y -> Microsoft.FSharp.Core.unit"] + "Method", ["type OverrideTests.B<'YY> original generics: <'Y> with member Method : () -> Microsoft.FSharp.Core.unit"] + "OverrideTests.I<'XX>.Method", ["type OverrideTests.I<'XX> original generics: <'X> with member Method : () -> Microsoft.FSharp.Core.unit"] + "NotOverride", [] + "add_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member add_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] + "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] + "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] + "OverrideTests.I<'XX>.get_Property", ["type OverrideTests.I<'XX> original generics: <'X> with member get_Property : () -> Microsoft.FSharp.Core.int"] + "remove_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member remove_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] + "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] + "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] + |] + |> Array.iter (fun x -> + if results |> Array.exists (fun y -> x = y) |> not then + failwithf "%A does not exist in the collection." x ) - |> Array.ofSeq - |> shouldEqual - [| - ".ctor", [] - "Generic", ["type OverrideTests.B<'YY> original generics: <'Y> with member Generic : 'Y -> Microsoft.FSharp.Core.unit"] - "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic : named:'X -> Microsoft.FSharp.Core.unit"] - "OverrideTests.I<'XX>.Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic<'Y> : 'X * 'Y -> Microsoft.FSharp.Core.unit"] - "Method", ["type OverrideTests.B<'YY> original generics: <'Y> with member Method : () -> Microsoft.FSharp.Core.unit"] - "OverrideTests.I<'XX>.Method", ["type OverrideTests.I<'XX> original generics: <'X> with member Method : () -> Microsoft.FSharp.Core.unit"] - "NotOverride", [] - "add_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member add_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] - "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] - "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] - "OverrideTests.I<'XX>.get_Property", ["type OverrideTests.I<'XX> original generics: <'X> with member get_Property : () -> Microsoft.FSharp.Core.int"] - "remove_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member remove_Event : Microsoft.FSharp.Control.Handler -> Microsoft.FSharp.Core.unit"] - "get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"] - "get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"] - |] //-------------------------------------------- From 5334b99fbcf83c73608c5c9281c96572ac397e70 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Fri, 23 Oct 2020 13:55:30 -0700 Subject: [PATCH 5/5] Fixing tests --- .../MemberDeclarations/E_ClashingInstanceStaticProperties.fs | 2 +- .../MemberDeclarations/E_PropertySameNameDiffArity.fs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs index 0be9356eab4..9c9455c5887 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_ClashingInstanceStaticProperties.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #ObjectOrientedTypes #Classes #MethodsAndProperties #MemberDefinitions // Regression test for FSHARP1.0:5475 -//Duplicate property\. The property 'M' has the same name and signature as another property in type 'C'\.$ +//Duplicate property\. The property 'M' has the same name and signature as another property in type 'C'\.$ type C = class member __.M = () static member M = () diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs index 29a80736286..94fe834a998 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/MemberDeclarations/E_PropertySameNameDiffArity.fs @@ -2,7 +2,7 @@ // Verify that one should not be able to have two properties called �X� with different arities (number of arguments). // This is regression test for FSHARP1.0:4529 -//The property 'X' has the same name as another property in type 'TestType1' +//The property 'X' has the same name as another property in type 'TestType1' type TestType1( x : int ) =