diff --git a/src/FSharpSource.targets b/src/FSharpSource.targets index 27b47b1c008..4c615d066c2 100644 --- a/src/FSharpSource.targets +++ b/src/FSharpSource.targets @@ -115,6 +115,7 @@ $(DefineConstants);FX_NO_EXCEPTIONDISPATCHINFO $(DefineConstants);FX_NO_TASK $(DefineConstants);FX_NO_IOBSERVABLE + $(DefineConstants);FX_NO_READONLY_COLLECTIONS $(DefineConstants);FX_NO_LAZY $(DefineConstants);FX_NO_TUPLE $(DefineConstants);FX_NO_MONITOR_REPORTS_LOCKTAKEN @@ -170,6 +171,7 @@ $(DefineConstants);FX_NO_APP_DOMAINS $(DefineConstants);FX_NO_PROCESS_DIAGNOSTICS $(DefineConstants);FX_NO_IOBSERVABLE + $(DefineConstants);FX_NO_READONLY_COLLECTIONS $(DefineConstants);FX_NO_WEB_CLIENT $(DefineConstants);FX_NO_CONVERTER $(DefineConstants);FX_NO_GET_HASH_CODE_HELPER @@ -525,6 +527,7 @@ $(DefineConstants);FX_NO_PARAMETERIZED_THREAD_START $(DefineConstants);FX_NO_STRUCTURAL_EQUALITY $(DefineConstants);FX_NO_IOBSERVABLE + $(DefineConstants);FX_NO_READONLY_COLLECTIONS $(DefineConstants);FX_NO_LAZY $(DefineConstants);FX_NO_TUPLE $(DefineConstants);FX_NO_DELEGATE_CREATE_DELEGATE_FROM_STATIC_METHOD diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index 0fa7edf74e2..eed87c4ca87 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -39,6 +39,17 @@ module ExtraTopLevelOperators = t.[RuntimeHelpers.StructBox(k)] <- v let d = (t :> IDictionary<_,_>) let c = (t :> ICollection<_>) + + let dictEnumerator (a: System.Collections.Generic.IEnumerator) = + { new System.Collections.IDictionaryEnumerator with + member x.Current = a.Current :> obj + member x.Entry = a.Current + member x.Key = x.Entry.Key + member x.Value = x.Entry.Value + member x.MoveNext () = a.MoveNext() + member x.Reset () = a.Reset() + } + // Give a read-only view of the dictionary { new IDictionary<'Key, 'T> with member s.Item @@ -70,6 +81,78 @@ module ExtraTopLevelOperators = let key = RuntimeHelpers.StructBox(k) if d.ContainsKey(key) then (r <- d.[key]; true) else false member s.Remove(k : 'Key) = (raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) : bool) +#if FX_NO_READONLY_COLLECTIONS +#else + interface IReadOnlyDictionary<'Key, 'T> with + member s.Item + with get x = d.[RuntimeHelpers.StructBox(x)] + member s.Keys = + let keys = d.Keys + { new IEnumerable<'Key> with + member s.GetEnumerator() = (keys |> Seq.map (fun v -> v.Value)).GetEnumerator() + interface System.Collections.IEnumerable with + member s.GetEnumerator() = ((keys |> Seq.map (fun v -> v.Value)) :> System.Collections.IEnumerable).GetEnumerator() } + + member s.Values = + { new IEnumerable<'T> with + member s.GetEnumerator() = d.Values.GetEnumerator() + interface System.Collections.IEnumerable with + member s.GetEnumerator() = (d.Values :> System.Collections.IEnumerable).GetEnumerator() } + member s.ContainsKey(k) = d.ContainsKey(RuntimeHelpers.StructBox(k)) + member s.TryGetValue(k,r) = + let key = RuntimeHelpers.StructBox(k) + if d.ContainsKey(key) then (r <- d.[key]; true) else false + interface IReadOnlyCollection> with + member s.Count = c.Count +#endif + interface System.Collections.IDictionary with + member s.IsReadOnly = true + member s.IsFixedSize = true + member s.IsSynchronized = true + member s.Item + with get x = d.[RuntimeHelpers.StructBox(x :?> 'Key)] :> obj + and set x v = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) + member s.Keys = + let keys = d.Keys + { new System.Collections.ICollection with + member s.CopyTo(arr,i) = + let mutable n = 0 + for k in keys do + arr.SetValue(k.Value,i+n) + n <- n + 1 + member s.IsSynchronized = true + member s.SyncRoot = (t :> System.Collections.ICollection).SyncRoot + member s.Count = keys.Count + interface System.Collections.IEnumerable with + member s.GetEnumerator() = ((keys |> Seq.map (fun v -> v.Value)) :> System.Collections.IEnumerable).GetEnumerator() } + + member s.Values = + { new System.Collections.ICollection with + member s.CopyTo(arr,i) = + let mutable n = 0 + for k in d.Values do + arr.SetValue(k,i+n) + n <- n + 1 + member s.IsSynchronized = true + member s.SyncRoot = (t :> System.Collections.ICollection).SyncRoot + member s.Count = d.Values.Count + interface System.Collections.IEnumerable with + member s.GetEnumerator() = (d.Values :> System.Collections.IEnumerable).GetEnumerator() } + member s.Count = c.Count + member s.SyncRoot = (t :> System.Collections.ICollection).SyncRoot + member s.Add(k,v) = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) + member s.Contains(k) = d.ContainsKey(RuntimeHelpers.StructBox(k :?> 'Key)) + member s.GetEnumerator() = + (c |> Seq.map (fun (KeyValue(k,v)) -> System.Collections.DictionaryEntry(k.Value,v))).GetEnumerator() + |> dictEnumerator + + member s.Remove(k) = (raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) : unit) + member s.Clear() = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))); + member s.CopyTo(arr,i) = + let mutable n = 0 + for (KeyValue(k,v)) in c do + arr.SetValue(System.Collections.DictionaryEntry(k.Value,v),i+n) + n <- n + 1 interface ICollection> with member s.Add(x) = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))); member s.Clear() = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated)));