Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2ccc1b3

Browse files
saulKevinRansom
authored andcommitted
Add debug visualiser for 'dict' and implement IReadOnlyDictionary/IReadOnlyCollection (dotnet#3988)
* Add debug visualiser for 'dict'* Review comments + implement IReadOnlyDictionary and IReadOnlyCollection* Add `readOnlyDict` to ExtraTopLevelOperators* Move extra top level operator tests* Fix broken tests* Add CreateReadOnlyDictionary to coreclr surface area
1 parentcb9e692 commit2ccc1b3

File tree

7 files changed

+337
-67
lines changed

7 files changed

+337
-67
lines changed

‎src/fsharp/FSharp.Core/fslib-extra-pervasives.fs‎

Lines changed: 100 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -40,59 +40,95 @@ module ExtraTopLevelOperators =
4040
let inlineICollection_Contains<'collection,'itemwhen'collection:>ICollection<'item>>(collection:'collection)(item:'item)=
4141
collection.Contains item
4242

43-
let inlinedictImpl(comparer:IEqualityComparer<'SafeKey>)(makeSafeKey:'Key->'SafeKey)(getKey:'SafeKey->'Key)(l:seq<'Key*'T>)=
43+
[<DebuggerDisplay("Count = {Count}")>]
44+
[<DebuggerTypeProxy(typedefof<DictDebugView<_,_,_>>)>]
45+
typeDictImpl<'SafeKey,'Key,'T>(t:Dictionary<'SafeKey,'T>,makeSafeKey: 'Key->'SafeKey,getKey: 'SafeKey->'Key)=
46+
47+
memberx.Count= t.Count
48+
49+
// Give a read-only view of the dictionary
50+
interface IDictionary<'Key, 'T>with
51+
members.Item
52+
with get x= dont_tail_call(fun()-> t.[makeSafeKey x])
53+
andset _ _= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)))
54+
members.Keys=
55+
letkeys= t.Keys
56+
{new ICollection<'Key>with
57+
members.Add(x)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
58+
members.Clear()= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
59+
members.Remove(x)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
60+
members.Contains(x)= t.ContainsKey(makeSafeKey x)
61+
members.CopyTo(arr,i)=
62+
let mutablen=0
63+
for kin keysdo
64+
arr.[i+n]<- getKey k
65+
n<- n+1
66+
members.IsReadOnly=true
67+
members.Count= keys.Count
68+
interface IEnumerable<'Key>with
69+
members.GetEnumerator()=(keys|> Seq.map getKey).GetEnumerator()
70+
interface System.Collections.IEnumerablewith
71+
members.GetEnumerator()=((keys|> Seq.map getKey):> System.Collections.IEnumerable).GetEnumerator()}
72+
73+
members.Values=upcast t.Values
74+
members.Add(_,_)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)))
75+
members.ContainsKey(k)= dont_tail_call(fun()-> t.ContainsKey(makeSafeKey k))
76+
members.TryGetValue(k,r)=
77+
letsafeKey= makeSafeKey k
78+
if t.ContainsKey(safeKey)then(r<- t.[safeKey];true)elsefalse
79+
members.Remove(_:'Key)=(raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))): bool)
80+
81+
interface IReadOnlyDictionary<'Key, 'T>with
82+
member__.Itemwith get key= t.[makeSafeKey key]
83+
member__.Keys= t.Keys|> Seq.map getKey
84+
member__.TryGetValue(key,r)=
85+
match t.TryGetValue(makeSafeKey key)with
86+
|false,_->false
87+
|true, value->
88+
r<- value
89+
true
90+
member__.Values=(t:> IReadOnlyDictionary<_,_>).Values
91+
member__.ContainsKey k= t.ContainsKey(makeSafeKey k)
92+
93+
interface ICollection<KeyValuePair<'Key, 'T>>with
94+
members.Add(_)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
95+
members.Clear()= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
96+
members.Remove(_)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
97+
members.Contains(KeyValue(k,v))= ICollection_Contains t(KeyValuePair<_,_>(makeSafeKey k,v))
98+
members.CopyTo(arr,i)=
99+
let mutablen=0
100+
for(KeyValue(k,v))in tdo
101+
arr.[i+n]<- KeyValuePair<_,_>(getKey k,v)
102+
n<- n+1
103+
members.IsReadOnly=true
104+
members.Count= t.Count
105+
106+
interface IReadOnlyCollection<KeyValuePair<'Key, 'T>>with
107+
member__.Count= t.Count
108+
109+
interface IEnumerable<KeyValuePair<'Key, 'T>>with
110+
members.GetEnumerator()=
111+
// We use an array comprehension here instead of seq {} as otherwise we get incorrect
112+
// IEnumerator.Reset() and IEnumerator.Current semantics.
113+
letkvps=[|for(KeyValue(k,v))in t-> KeyValuePair(getKey k, v)|]:> seq<_>
114+
kvps.GetEnumerator()
115+
116+
interface System.Collections.IEnumerablewith
117+
members.GetEnumerator()=
118+
// We use an array comprehension here instead of seq {} as otherwise we get incorrect
119+
// IEnumerator.Reset() and IEnumerator.Current semantics.
120+
letkvps=[|for(KeyValue(k,v))in t-> KeyValuePair(getKey k, v)|]:> System.Collections.IEnumerable
121+
kvps.GetEnumerator()
122+
123+
andDictDebugView<'SafeKey,'Key,'T>(d:DictImpl<'SafeKey,'Key,'T>)=
124+
[<DebuggerBrowsable(DebuggerBrowsableState.RootHidden)>]
125+
memberx.Items= Array.ofSeq d
126+
127+
let inlinedictImpl(comparer:IEqualityComparer<'SafeKey>)(makeSafeKey:'Key->'SafeKey)(getKey:'SafeKey->'Key)(l:seq<'Key*'T>)=
44128
lett= Dictionary comparer
45-
for(k,v)in ldo
129+
for(k,v)in ldo
46130
t.[makeSafeKey k]<- v
47-
// Give a read-only view of the dictionary
48-
{new IDictionary<'Key, 'T>with
49-
members.Item
50-
with get x= dont_tail_call(fun()-> t.[makeSafeKey x])
51-
andset x v= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)))
52-
members.Keys=
53-
letkeys= t.Keys
54-
{new ICollection<'Key>with
55-
members.Add(x)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
56-
members.Clear()= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
57-
members.Remove(x)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
58-
members.Contains(x)= t.ContainsKey(makeSafeKey x)
59-
members.CopyTo(arr,i)=
60-
let mutablen=0
61-
for kin keysdo
62-
arr.[i+n]<- getKey k
63-
n<- n+1
64-
members.IsReadOnly=true
65-
members.Count= keys.Count
66-
interface IEnumerable<'Key>with
67-
members.GetEnumerator()=(keys|> Seq.map getKey).GetEnumerator()
68-
interface System.Collections.IEnumerablewith
69-
members.GetEnumerator()=((keys|> Seq.map getKey):> System.Collections.IEnumerable).GetEnumerator()}
70-
71-
members.Values=upcast t.Values
72-
members.Add(k,v)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)))
73-
members.ContainsKey(k)= dont_tail_call(fun()-> t.ContainsKey(makeSafeKey k))
74-
members.TryGetValue(k,r)=
75-
letsafeKey= makeSafeKey k
76-
if t.ContainsKey(safeKey)then(r<- t.[safeKey];true)elsefalse
77-
members.Remove(k:'Key)=(raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))): bool)
78-
interface ICollection<KeyValuePair<'Key, 'T>>with
79-
members.Add(x)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
80-
members.Clear()= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
81-
members.Remove(x)= raise(NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));
82-
members.Contains(KeyValue(k,v))= ICollection_Contains t(KeyValuePair<_,_>(makeSafeKey k,v))
83-
members.CopyTo(arr,i)=
84-
let mutablen=0
85-
for(KeyValue(k,v))in tdo
86-
arr.[i+n]<- KeyValuePair<_,_>(getKey k,v)
87-
n<- n+1
88-
members.IsReadOnly=true
89-
members.Count= t.Count
90-
interface IEnumerable<KeyValuePair<'Key, 'T>>with
91-
members.GetEnumerator()=
92-
(t|> Seq.map(fun(KeyValue(k,v))-> KeyValuePair<_,_>(getKey k,v))).GetEnumerator()
93-
interface System.Collections.IEnumerablewith
94-
members.GetEnumerator()=
95-
((t|> Seq.map(fun(KeyValue(k,v))-> KeyValuePair<_,_>(getKey k,v))):> System.Collections.IEnumerable).GetEnumerator()}
131+
DictImpl(t, makeSafeKey, getKey)
96132

97133
// We avoid wrapping a StructBox, because under 64 JIT we get some "hard" tailcalls which affect performance
98134
letdictValueType(l:seq<'Key*'T>)= dictImpl HashIdentity.Structural<'Key> id id l
@@ -101,14 +137,24 @@ module ExtraTopLevelOperators =
101137
letdictRefType(l:seq<'Key*'T>)= dictImpl RuntimeHelpers.StructBox<'Key>.Comparer(fun k-> RuntimeHelpers.StructBox k)(fun sb-> sb.Value) l
102138

103139
[<CompiledName("CreateDictionary")>]
104-
letdict(keyValuePairs:seq<'Key*'T>)=
140+
letdict(keyValuePairs:seq<'Key*'T>):IDictionary<'Key,'T>=
141+
#if FX_RESHAPED_REFLECTION
142+
if(typeof<'Key>).GetTypeInfo().IsValueType
143+
#else
144+
if typeof<'Key>.IsValueType
145+
#endif
146+
then dictValueType keyValuePairs:>_
147+
else dictRefType keyValuePairs:>_
148+
149+
[<CompiledName("CreateReadOnlyDictionary")>]
150+
letreadOnlyDict(keyValuePairs:seq<'Key*'T>):IReadOnlyDictionary<'Key,'T>=
105151
#if FX_RESHAPED_REFLECTION
106152
if(typeof<'Key>).GetTypeInfo().IsValueType
107153
#else
108154
if typeof<'Key>.IsValueType
109155
#endif
110-
then dictValueType keyValuePairs
111-
else dictRefType keyValuePairs
156+
then dictValueType keyValuePairs:>_
157+
else dictRefType keyValuePairs:>_
112158

113159
letgetArray(vals:seq<'T>)=
114160
match valswith

‎src/fsharp/FSharp.Core/fslib-extra-pervasives.fsi‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ module ExtraTopLevelOperators =
122122
[<CompiledName("CreateDictionary")>]
123123
val dict:keyValuePairs:seq<'Key* 'Value>->System.Collections.Generic.IDictionary<'Key,'Value> when 'Key:equality
124124

125+
///<summary>Builds a read-only lookup table from a sequence of key/value pairs. The key objects are indexed using generic hashing and equality.</summary>
126+
[<CompiledName("CreateReadOnlyDictionary")>]
127+
val readOnlyDict:keyValuePairs:seq<'Key* 'Value>->System.Collections.Generic.IReadOnlyDictionary<'Key,'Value> when 'Key:equality
128+
125129
///<summary>Builds a 2D array from a sequence of sequences of elements.</summary>
126130
[<CompiledName("CreateArray2D")>]
127131
val array2D:rows:seq<#seq<'T>>-> 'T[,]

‎tests/FSharp.Core.UnitTests/FSharp.Core.Unittests.fsproj‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<ErrorReport>prompt</ErrorReport>
4040
<WarningLevel>3</WarningLevel>
4141
</PropertyGroup>
42-
<ItemGroupCondition=" '$(TargetDotnetProfile)' != 'coreclr'">
42+
<ItemGroupCondition=" '$(TargetDotnetProfile)' != 'coreclr'">
4343
<!-- need full name and SpecificVersion = true in order to convince msbuild to allow this reference when targeting portable47-->
4444
<ReferenceInclude="nunit.framework, Version=$(NUnitFullVersion), Culture=neutral, PublicKeyToken=2638cd05610744eb">
4545
<SpecificVersion>true</SpecificVersion>
@@ -105,6 +105,7 @@
105105
<CompileInclude="FSharp.Core\Microsoft.FSharp.Core\OptionModule.fs" />
106106
<CompileInclude="FSharp.Core\Microsoft.FSharp.Core\PrintfTests.fs" />
107107
<CompileInclude="FSharp.Core\Microsoft.FSharp.Core\ResultTests.fs" />
108+
<CompileInclude="FSharp.Core\Microsoft.FSharp.Core\ExtraTopLevelOperatorsTests.fs" />
108109
<CompileInclude="FSharp.Core\Microsoft.FSharp.Control\Cancellation.fs" />
109110
<CompileInclude="FSharp.Core\Microsoft.FSharp.Control\AsyncType.fs" />
110111
<CompileInclude="FSharp.Core\Microsoft.FSharp.Control\LazyType.fs" />
@@ -125,4 +126,4 @@
125126
</CopyAndSubstituteText>
126127
</ItemGroup>
127128
<ImportProject="$(FSharpSourcesRoot)\FSharpSource.targets" />
128-
</Project>
129+
</Project>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp