Skip to content

Commit 7e31494

Browse files
authored
Add reference assembly for System.Private.CoreLib.dll (#75311)
We now compile against the reference assembly in all places where we were compiling against the mono/coreclr System.Private.CoreLib.dll implementation assembly before. The new reference assembly consumes sources from the existing contracts to avoid checking in a generated version of SPC.dll (this would add ~20k lines of .cs which is mostly duplicated with System.Runtime.cs) Since a few contracts have only partially moved types to SPC we wrap contract types with `#if !BUILDING_CORELIB_REFERENCE` so we can hide them when compiling the SPC reference assembly.
1 parent bc65e68 commit 7e31494

File tree

17 files changed

+378
-8
lines changed

17 files changed

+378
-8
lines changed

Directory.Build.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,10 @@
237237

238238
<PropertyGroup>
239239
<CoreLibSharedDir>$([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'System.Private.CoreLib', 'src'))</CoreLibSharedDir>
240+
<CoreLibRefDir>$([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'System.Private.CoreLib', 'ref'))</CoreLibRefDir>
240241
<CoreLibProject Condition="'$(RuntimeFlavor)' == 'CoreCLR'">$([MSBuild]::NormalizePath('$(CoreClrProjectRoot)', 'System.Private.CoreLib', 'System.Private.CoreLib.csproj'))</CoreLibProject>
241242
<CoreLibProject Condition="'$(RuntimeFlavor)' == 'Mono'">$([MSBuild]::NormalizePath('$(MonoProjectRoot)', 'System.Private.CoreLib', 'System.Private.CoreLib.csproj'))</CoreLibProject>
243+
<UriProject>$([MSBuild]::NormalizePath('$(LibrariesProjectRoot)', 'System.Private.Uri', 'src', 'System.Private.Uri.csproj'))</UriProject>
242244

243245
<!-- this property is used by the SDK to pull in mono-based runtime packs -->
244246
<UseMonoRuntime Condition="'$(UseMonoRuntime)' == '' and '$(RuntimeFlavor)' == 'Mono'">true</UseMonoRuntime>

docs/coding-guidelines/updating-ref-source.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This document provides the steps you need to take to update the reference assemb
1313

1414
These steps can also be applied to some unique assemblies which depend on changes in System.Private.Corelib. (partial facades like System.Memory, for example).
1515

16-
1) Run `dotnet build --no-incremental /t:GenerateReferenceSource` from the System.Runtime/src directory.
16+
1) Run `dotnet build --no-incremental /t:GenerateReferenceAssemblySource` from the System.Runtime/src directory.
1717
2) Filter out all unrelated changes and extract the changes you care about (ignore certain attributes being removed). Generally, this step is not required for other reference assemblies.
1818

1919
## For Full Facade Assemblies implementation assemblies

eng/references.targets

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,15 @@
5959
<Error Condition="'%(ReferencePath.ReferenceSourceTarget)' == 'ProjectReference' AND '%(ReferencePath.IsReferenceAssembly)' != 'true' AND '%(ReferencePath.ReferenceAssembly)' == ''"
6060
Text="Reference assemblies must only reference other reference assemblies and '%(ReferencePath.ProjectReferenceOriginalItemSpec)' is not a reference assembly project and does not set 'ProduceReferenceAssembly'." />
6161
</Target>
62+
63+
<Target Name="ReplaceCoreLibSrcWithRefAssemblyForCompilation"
64+
AfterTargets="FindReferenceAssembliesForReferences"
65+
Condition="'$(CompileUsingReferenceAssemblies)' != 'true' and '@(_coreLibProjectReference)' != ''">
66+
<ItemGroup>
67+
<_resolvedCoreLibProjectReference Include="@(_ResolvedProjectReferencePaths->WithMetadataValue('MSBuildSourceProjectFile','$(CoreLibProject)'))" />
68+
<ReferencePathWithRefAssemblies Remove="@(_resolvedCoreLibProjectReference)" />
69+
<ReferencePathWithRefAssemblies Include="@(_resolvedCoreLibProjectReference->Metadata('ReferenceAssembly'))" />
70+
</ItemGroup>
71+
</Target>
72+
6273
</Project>

src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<EnableDefaultItems>false</EnableDefaultItems>
@@ -355,4 +355,10 @@
355355
<FileWrites Include="@(EventingSourceFile)" />
356356
</ItemGroup>
357357
</Target>
358+
359+
<!-- Import refererence assembly logic -->
360+
<PropertyGroup>
361+
<IsSourceProject>true</IsSourceProject>
362+
</PropertyGroup>
363+
<Import Project="$(RepositoryEngineeringDir)resolveContract.targets" />
358364
</Project>

src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace System.Collections.Concurrent
88
{
9+
#if !BUILDING_CORELIB_REFERENCE
910
[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
1011
public partial class BlockingCollection<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection, System.Collections.IEnumerable, System.IDisposable
1112
{
@@ -126,6 +127,7 @@ void System.Collections.IDictionary.Remove(object key) { }
126127
public bool TryRemove(TKey key, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TValue value) { throw null; }
127128
public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue) { throw null; }
128129
}
130+
#endif
129131
public partial class ConcurrentQueue<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection, System.Collections.IEnumerable
130132
{
131133
public ConcurrentQueue() { }
@@ -146,6 +148,7 @@ void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
146148
public bool TryDequeue([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T result) { throw null; }
147149
public bool TryPeek([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T result) { throw null; }
148150
}
151+
#if !BUILDING_CORELIB_REFERENCE
149152
public partial class ConcurrentStack<T> : System.Collections.Concurrent.IProducerConsumerCollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection, System.Collections.IEnumerable
150153
{
151154
public ConcurrentStack() { }
@@ -176,13 +179,15 @@ public enum EnumerablePartitionerOptions
176179
None = 0,
177180
NoBuffering = 1,
178181
}
182+
#endif
179183
public partial interface IProducerConsumerCollection<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.ICollection, System.Collections.IEnumerable
180184
{
181185
void CopyTo(T[] array, int index);
182186
T[] ToArray();
183187
bool TryAdd(T item);
184188
bool TryTake([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T item);
185189
}
190+
#if !BUILDING_CORELIB_REFERENCE
186191
public abstract partial class OrderablePartitioner<TSource> : System.Collections.Concurrent.Partitioner<TSource>
187192
{
188193
protected OrderablePartitioner(bool keysOrderedInEachPartition, bool keysOrderedAcrossPartitions, bool keysNormalized) { }
@@ -212,4 +217,5 @@ protected Partitioner() { }
212217
public virtual System.Collections.Generic.IEnumerable<TSource> GetDynamicPartitions() { throw null; }
213218
public abstract System.Collections.Generic.IList<System.Collections.Generic.IEnumerator<TSource>> GetPartitions(int partitionCount);
214219
}
220+
#endif
215221
}

src/libraries/System.Collections/ref/System.Collections.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace System.Collections
88
{
9+
#if !BUILDING_CORELIB_REFERENCE
910
public sealed partial class BitArray : System.Collections.ICollection, System.Collections.IEnumerable, System.ICloneable
1011
{
1112
public BitArray(bool[] values) { }
@@ -38,16 +39,20 @@ public static partial class StructuralComparisons
3839
public static System.Collections.IComparer StructuralComparer { get { throw null; } }
3940
public static System.Collections.IEqualityComparer StructuralEqualityComparer { get { throw null; } }
4041
}
42+
#endif
4143
}
44+
4245
namespace System.Collections.Generic
4346
{
47+
#if !BUILDING_CORELIB_REFERENCE
4448
public static partial class CollectionExtensions
4549
{
4650
public static TValue? GetValueOrDefault<TKey, TValue>(this System.Collections.Generic.IReadOnlyDictionary<TKey, TValue> dictionary, TKey key) { throw null; }
4751
public static TValue GetValueOrDefault<TKey, TValue>(this System.Collections.Generic.IReadOnlyDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue) { throw null; }
4852
public static bool Remove<TKey, TValue>(this System.Collections.Generic.IDictionary<TKey, TValue> dictionary, TKey key, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TValue value) { throw null; }
4953
public static bool TryAdd<TKey, TValue>(this System.Collections.Generic.IDictionary<TKey, TValue> dictionary, TKey key, TValue value) { throw null; }
5054
}
55+
#endif
5156
public abstract partial class Comparer<T> : System.Collections.Generic.IComparer<T>, System.Collections.IComparer
5257
{
5358
protected Comparer() { }
@@ -240,6 +245,7 @@ public void Dispose() { }
240245
void System.Collections.IEnumerator.Reset() { }
241246
}
242247
}
248+
#if !BUILDING_CORELIB_REFERENCE
243249
public sealed partial class LinkedListNode<T>
244250
{
245251
public LinkedListNode(T value) { }
@@ -298,6 +304,7 @@ void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(obj
298304
void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
299305
}
300306
}
307+
#endif
301308
public partial class List<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
302309
{
303310
public List() { }
@@ -379,7 +386,7 @@ public void Dispose() { }
379386
void System.Collections.IEnumerator.Reset() { }
380387
}
381388
}
382-
389+
#if !BUILDING_CORELIB_REFERENCE
383390
public partial class PriorityQueue<TElement, TPriority>
384391
{
385392
public PriorityQueue() { }
@@ -423,7 +430,7 @@ void System.Collections.IEnumerator.Reset() { }
423430
}
424431
}
425432
}
426-
433+
#endif
427434
public partial class Queue<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection, System.Collections.IEnumerable
428435
{
429436
public Queue() { }
@@ -466,6 +473,7 @@ private ReferenceEqualityComparer() { }
466473
public new bool Equals(object? x, object? y) { throw null; }
467474
public int GetHashCode(object? obj) { throw null; }
468475
}
476+
#if !BUILDING_CORELIB_REFERENCE
469477
public partial class SortedDictionary<TKey, TValue> : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IDictionary<TKey, TValue>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyDictionary<TKey, TValue>, System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable where TKey : notnull
470478
{
471479
public SortedDictionary() { }
@@ -718,4 +726,5 @@ public void Dispose() { }
718726
void System.Collections.IEnumerator.Reset() { }
719727
}
720728
}
729+
#endif
721730
}

src/libraries/System.Diagnostics.Debug/tests/System.Diagnostics.Debug.Tests.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<RootNamespace>System.Diagnostics.Tests</RootNamespace>
4-
<IgnoreArchitectureMismatches>true</IgnoreArchitectureMismatches>
5-
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
64
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-Unix</TargetFrameworks>
75
<TestRuntime>true</TestRuntime>
6+
<!-- Some tests need types like System.Diagnostics.DebugProvider which are only exposed from System.Private.CoreLib -->
7+
<CompileUsingReferenceAssemblies>false</CompileUsingReferenceAssemblies>
88
</PropertyGroup>
99
<ItemGroup>
1010
<DefaultReferenceExclusion Include="System.Diagnostics.Debug" />
1111
<DefaultReferenceExclusion Include="System.Runtime.Extensions" />
1212
<ProjectReference Include="$(CoreLibProject)" />
1313
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime\src\System.Runtime.csproj" />
14-
<ProjectReference Include="$(LibrariesProjectRoot)System.Threading\src\System.Threading.csproj" SkipUseReferenceAssembly="true" />
14+
<ProjectReference Include="$(LibrariesProjectRoot)System.Threading\src\System.Threading.csproj" />
15+
<ProjectReference Include="$(LibrariesProjectRoot)System.Collections\src\System.Collections.csproj" />
1516
</ItemGroup>
1617
<ItemGroup>
1718
<Compile Include="DebugTests.cs" />

src/libraries/System.Diagnostics.StackTrace/ref/System.Diagnostics.StackTrace.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public StackTrace(int skipFrames, bool fNeedFileInfo) { }
5252
}
5353
namespace System.Diagnostics.SymbolStore
5454
{
55+
#if !BUILDING_CORELIB_REFERENCE
5556
public partial interface ISymbolBinder
5657
{
5758
[System.ObsoleteAttribute("ISymbolBinder.GetReader has been deprecated because it is not 64-bit compatible. Use ISymbolBinder1.GetReader instead. ISymbolBinder1.GetReader accepts the importer interface pointer as an IntPtr instead of an Int32, and thus works on both 32-bit and 64-bit architectures.")]
@@ -74,11 +75,13 @@ public partial interface ISymbolDocument
7475
byte[] GetCheckSum();
7576
byte[] GetSourceRange(int startLine, int startColumn, int endLine, int endColumn);
7677
}
78+
#endif
7779
public partial interface ISymbolDocumentWriter
7880
{
7981
void SetCheckSum(System.Guid algorithmId, byte[] checkSum);
8082
void SetSource(byte[] source);
8183
}
84+
#if !BUILDING_CORELIB_REFERENCE
8285
public partial interface ISymbolMethod
8386
{
8487
System.Diagnostics.SymbolStore.ISymbolScope RootScope { get; }
@@ -205,4 +208,5 @@ public partial class SymLanguageVendor
205208
public static readonly System.Guid Microsoft;
206209
public SymLanguageVendor() { }
207210
}
211+
#endif
208212
}

src/libraries/System.Memory/ref/System.Memory.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ public ref struct TryWriteInterpolatedStringHandler
165165
public bool AppendFormatted(string? value, int alignment = 0, string? format = null) { throw null; }
166166
}
167167
}
168+
#if !BUILDING_CORELIB_REFERENCE
168169
public readonly partial struct SequencePosition : System.IEquatable<System.SequencePosition>
169170
{
170171
private readonly object _dummy;
@@ -180,9 +181,11 @@ public ref struct TryWriteInterpolatedStringHandler
180181
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
181182
public object? GetObject() { throw null; }
182183
}
184+
#endif
183185
}
184186
namespace System.Buffers
185187
{
188+
#if !BUILDING_CORELIB_REFERENCE
186189
public sealed partial class ArrayBufferWriter<T> : System.Buffers.IBufferWriter<T>
187190
{
188191
public ArrayBufferWriter() { }
@@ -315,6 +318,7 @@ public void Rewind(long count) { }
315318
public bool TryReadToAny(out System.Buffers.ReadOnlySequence<T> sequence, System.ReadOnlySpan<T> delimiters, bool advancePastDelimiter = true) { throw null; }
316319
public bool TryReadToAny(out System.ReadOnlySpan<T> span, System.ReadOnlySpan<T> delimiters, bool advancePastDelimiter = true) { throw null; }
317320
}
321+
#endif
318322
public readonly partial struct StandardFormat : System.IEquatable<System.Buffers.StandardFormat>
319323
{
320324
private readonly int _dummyPrimitive;
@@ -541,16 +545,19 @@ public static partial class MemoryMarshal
541545
public static bool TryWrite<T>(System.Span<byte> destination, ref T value) where T : struct { throw null; }
542546
public static void Write<T>(System.Span<byte> destination, ref T value) where T : struct { }
543547
}
548+
#if !BUILDING_CORELIB_REFERENCE
544549
public static partial class SequenceMarshal
545550
{
546551
public static bool TryGetArray<T>(System.Buffers.ReadOnlySequence<T> sequence, out System.ArraySegment<T> segment) { throw null; }
547552
public static bool TryGetReadOnlyMemory<T>(System.Buffers.ReadOnlySequence<T> sequence, out System.ReadOnlyMemory<T> memory) { throw null; }
548553
public static bool TryGetReadOnlySequenceSegment<T>(System.Buffers.ReadOnlySequence<T> sequence, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Buffers.ReadOnlySequenceSegment<T>? startSegment, out int startIndex, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Buffers.ReadOnlySequenceSegment<T>? endSegment, out int endIndex) { throw null; }
549554
public static bool TryRead<T>(ref System.Buffers.SequenceReader<byte> reader, out T value) where T : unmanaged { throw null; }
550555
}
556+
#endif
551557
}
552558
namespace System.Text
553559
{
560+
#if !BUILDING_CORELIB_REFERENCE
554561
public static partial class EncodingExtensions
555562
{
556563
public static void Convert(this System.Text.Decoder decoder, in System.Buffers.ReadOnlySequence<byte> bytes, System.Buffers.IBufferWriter<char> writer, bool flush, out long charsUsed, out bool completed) { throw null; }
@@ -566,6 +573,7 @@ public static partial class EncodingExtensions
566573
public static long GetChars(this System.Text.Encoding encoding, System.ReadOnlySpan<byte> bytes, System.Buffers.IBufferWriter<char> writer) { throw null; }
567574
public static string GetString(this System.Text.Encoding encoding, in System.Buffers.ReadOnlySequence<byte> bytes) { throw null; }
568575
}
576+
#endif
569577
public ref partial struct SpanLineEnumerator
570578
{
571579
private object _dummy;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
// NOTE: Types/members which are not publicly exposed in System.Runtime.dll but still used internally by libraries.
5+
// Manually maintained, keep in sync with System.Private.CoreLib.ExtraApis.txt
6+
7+
namespace System.Runtime.Serialization
8+
{
9+
public readonly partial struct DeserializationToken : System.IDisposable
10+
{
11+
#pragma warning disable CS0414
12+
private readonly object _dummy = null;
13+
private readonly int _dummyPrimitive = 0;
14+
#pragma warning restore CS0414
15+
internal DeserializationToken(object tracker) { }
16+
public void Dispose() { }
17+
}
18+
public sealed partial class SerializationInfo
19+
{
20+
public static System.Runtime.Serialization.DeserializationToken StartDeserialization() { throw null; }
21+
}
22+
}
23+
namespace System.Diagnostics
24+
{
25+
public partial class DebugProvider
26+
{
27+
public DebugProvider() { }
28+
[System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
29+
public virtual void Fail(string? message, string? detailMessage) { throw null; }
30+
public static void FailCore(string stackTrace, string? message, string? detailMessage, string errorSource) { }
31+
public virtual void OnIndentLevelChanged(int indentLevel) { }
32+
public virtual void OnIndentSizeChanged(int indentSize) { }
33+
public virtual void Write(string? message) { }
34+
public static void WriteCore(string message) { }
35+
public virtual void WriteLine(string? message) { }
36+
}
37+
public static partial class Debug
38+
{
39+
public static System.Diagnostics.DebugProvider SetProvider(System.Diagnostics.DebugProvider provider) { throw null; }
40+
}
41+
}

0 commit comments

Comments
 (0)