Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove experimental label from FakeTimeProvider #4259

Merged
merged 1 commit into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ private static void ReportDiagnosticForModel(CompilationAnalysisContext context,
var compilation = context.Compilation;
var obsoleteAttribute = compilation.GetTypeByMetadataName(ObsoleteAttributeFullName);

// flag symbols found in the code, but not in the model
// #1. flag symbols found in the code, but not in the model

foreach (var symbol in assemblyAnalysis.NotFoundInBaseline)
{
if (!symbol.IsContaminated(ExperimentalAttributeFullName))
Expand All @@ -76,7 +77,7 @@ private static void ReportDiagnosticForModel(CompilationAnalysisContext context,
}
}

// flag any stable or deprecated API in the model, but not in the assembly
// #2. flag any stable or deprecated API in the model, but not in the assembly

foreach (var type in assemblyAnalysis.MissingTypes.Where(x => x.Stage != Stage.Experimental))
{
Expand All @@ -98,19 +99,15 @@ private static void ReportDiagnosticForModel(CompilationAnalysisContext context,
context.ReportDiagnostic(Diagnostic.Create(DiagDescriptors.PublishedSymbolsCantBeDeleted, null, field.Member));
}

// now make sure attributes are applied correctly
// #3. make sure attributes are applied correctly

foreach (var (symbol, stage) in assemblyAnalysis.FoundInBaseline)
{
var isMarkedExperimental = symbol.IsContaminated(ExperimentalAttributeFullName);
var isMarkedObsolete = symbol.IsContaminated(obsoleteAttribute);

if (stage == Stage.Experimental)
{
if (!isMarkedExperimental)
{
context.ReportDiagnostic(Diagnostic.Create(DiagDescriptors.NewSymbolsMustBeMarkedExperimental, symbol.Locations.FirstOrDefault(), symbol));
}

if (isMarkedObsolete)
{
context.ReportDiagnostic(Diagnostic.Create(DiagDescriptors.ExperimentalSymbolsCantBeMarkedObsolete, symbol.Locations.FirstOrDefault(), symbol));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Threading;
using Microsoft.Extensions.Time.Testing;
using Microsoft.Shared.DiagnosticIds;
using Microsoft.Shared.Diagnostics;

namespace Microsoft.Extensions.Time.Testing;

/// <summary>
/// A synthetic time provider used to enable deterministic behavior in tests.
/// </summary>
[Experimental(diagnosticId: Experiments.TimeProvider, UrlFormat = Experiments.UrlFormat)]
public class FakeTimeProvider : TimeProvider
{
internal readonly HashSet<Waiter> Waiters = new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,61 @@
"Types": [
{
"Type": "class Microsoft.Extensions.Time.Testing.FakeTimeProvider : System.TimeProvider",
"Stage": "Experimental",
"Stage": "Stable",
"Methods": [
{
"Member": "Microsoft.Extensions.Time.Testing.FakeTimeProvider.FakeTimeProvider();",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "Microsoft.Extensions.Time.Testing.FakeTimeProvider.FakeTimeProvider(System.DateTimeOffset startDateTime);",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "void Microsoft.Extensions.Time.Testing.FakeTimeProvider.Advance(System.TimeSpan delta);",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "override System.Threading.ITimer Microsoft.Extensions.Time.Testing.FakeTimeProvider.CreateTimer(System.Threading.TimerCallback callback, object? state, System.TimeSpan dueTime, System.TimeSpan period);",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "override long Microsoft.Extensions.Time.Testing.FakeTimeProvider.GetTimestamp();",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "override System.DateTimeOffset Microsoft.Extensions.Time.Testing.FakeTimeProvider.GetUtcNow();",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "void Microsoft.Extensions.Time.Testing.FakeTimeProvider.SetLocalTimeZone(System.TimeZoneInfo localTimeZone);",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "void Microsoft.Extensions.Time.Testing.FakeTimeProvider.SetUtcNow(System.DateTimeOffset value);",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "override string Microsoft.Extensions.Time.Testing.FakeTimeProvider.ToString();",
"Stage": "Experimental"
"Stage": "Stable"
}
],
"Properties": [
{
"Member": "System.TimeSpan Microsoft.Extensions.Time.Testing.FakeTimeProvider.AutoAdvanceAmount { get; set; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "override System.TimeZoneInfo Microsoft.Extensions.Time.Testing.FakeTimeProvider.LocalTimeZone { get; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "System.DateTimeOffset Microsoft.Extensions.Time.Testing.FakeTimeProvider.Start { get; }",
"Stage": "Experimental"
"Stage": "Stable"
},
{
"Member": "override long Microsoft.Extensions.Time.Testing.FakeTimeProvider.TimestampFrequency { get; }",
"Stage": "Experimental"
"Stage": "Stable"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ public async Task Analyzer_Reports_Diagnostics_When_Code_Was_Not_Annotated_Corre
}
}

private const string AttributeDefinition = @"
namespace System.Diagnostics.CodeAnalysis;
internal sealed class ExperimentalAttribute : System.Attribute { }
";

[Theory]
[MemberData(nameof(CodeWithMissingMembers))]
public async Task Analyzer_Reports_Diagnostics_When_StableCode_Was_Not_Found_In_The_Compilation(int expectedDiagnostics, string fileName,
Expand All @@ -66,7 +61,6 @@ public async Task Analyzer_Reports_Diagnostics_When_StableCode_Was_Not_Found_In_
sources: new[]
{
"[assembly: System.Runtime.Versioning.TargetFramework(\".NETCoreApp,Version=v6.0\")]",
AttributeDefinition,
source
},
options: options,
Expand Down Expand Up @@ -126,7 +120,6 @@ public enum SimpleTaxonomy : ulong

"
},
#if false
new object[]
{
1,
Expand Down Expand Up @@ -228,7 +221,7 @@ namespace Microsoft.Extensions.Security.Identity;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public class AdditionalContext2
{
protected IReadOnlyDictionary<string, object> Features { get; } = new Dictionary<string, object>();
Expand Down Expand Up @@ -347,7 +340,7 @@ public sealed class BufferWriter2<T> : IBufferWriter<T>

private T[] _buffer = Array.Empty<T>();

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public BufferWriter2() { }

public ReadOnlyMemory<T> WrittenMemory => _buffer.AsMemory(0, WrittenCount);
Expand Down Expand Up @@ -393,7 +386,6 @@ private void EnsureCapacity(int sizeHint)
}
"
},

new object[]
{
0,
Expand Down Expand Up @@ -474,7 +466,7 @@ public interface IClassifiedData
public DataClass DataClass { get; }
}

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public enum DataClass
{

Expand Down Expand Up @@ -562,10 +554,10 @@ namespace SomePackage;

using System.Diagnostics.CodeAnalysis;

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public static class Test
{
[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public static void Load()
{
// Intentionally left empty.
Expand Down Expand Up @@ -707,7 +699,7 @@ namespace Microsoft.Extensions.Diagnostics;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public class WindowsCountersOptions2
{
[Required]
Expand All @@ -728,7 +720,7 @@ namespace Test;

using System.Diagnostics.CodeAnalysis;

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public sealed class BufferWriter<T>
{
internal const int MaxArrayLength = 0X7FEF_FFFF; // Copy of the internal Array.MaxArrayLength const
Expand All @@ -751,7 +743,7 @@ namespace Inheritance;

using System.Diagnostics.CodeAnalysis;

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public class BaseType
{
public virtual int P => 1;
Expand All @@ -774,7 +766,7 @@ namespace Nested;

using System.Diagnostics.CodeAnalysis;

[Experimental(diagnosticId: "TBD", UrlFormat = "TBD")]
[Experimental(diagnosticId: ""TBD"", UrlFormat = ""TBD"")]
public class OuterType
{
public int ReadValue(string s) => new InnerType().P;
Expand All @@ -786,11 +778,40 @@ public class InnerType
}
"
}
#endif
};

public static IEnumerable<object[]> CodeWithMissingApis => new List<object[]>
{
new object[]
{
0,
"ApiLifecycle/Data/Microsoft.Extensions.TimeProvider.Testing.json",
"Microsoft.Extensions.TimeProvider.Testing",
DiagDescriptors.NewSymbolsMustBeMarkedExperimental,
@"
using System;
using System.Threading;

namespace Microsoft.Extensions.Time.Testing;

public class FakeTimeProvider : TimeProvider
{
public FakeTimeProvider() { }
public FakeTimeProvider(DateTimeOffset startDateTime) { }
public DateTimeOffset Start { get; }
public TimeSpan AutoAdvanceAmount { get; set; }
public override DateTimeOffset GetUtcNow() => default;
public void SetUtcNow(DateTimeOffset value) { }
public void Advance(TimeSpan delta) { }
public override long GetTimestamp() => 0;
public override TimeZoneInfo LocalTimeZone => null!;
public void SetLocalTimeZone(TimeZoneInfo localTimeZone) { }
public override long TimestampFrequency => 0;
public override string ToString() => string.Empty;
public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period) => null!;
}
"
},
new object[]
{
1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"Name": "Microsoft.Extensions.TimeProvider.Testing, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"Types": [
{
"Type": "class Microsoft.Extensions.Time.Testing.FakeTimeProvider : System.TimeProvider",
"Stage": "Experimental",
"Methods": [
{
"Member": "Microsoft.Extensions.Time.Testing.FakeTimeProvider.FakeTimeProvider();",
"Stage": "Experimental"
},
{
"Member": "Microsoft.Extensions.Time.Testing.FakeTimeProvider.FakeTimeProvider(System.DateTimeOffset startDateTime);",
"Stage": "Experimental"
},
{
"Member": "void Microsoft.Extensions.Time.Testing.FakeTimeProvider.Advance(System.TimeSpan delta);",
"Stage": "Experimental"
},
{
"Member": "override System.Threading.ITimer Microsoft.Extensions.Time.Testing.FakeTimeProvider.CreateTimer(System.Threading.TimerCallback callback, object? state, System.TimeSpan dueTime, System.TimeSpan period);",
"Stage": "Experimental"
},
{
"Member": "override long Microsoft.Extensions.Time.Testing.FakeTimeProvider.GetTimestamp();",
"Stage": "Experimental"
},
{
"Member": "override System.DateTimeOffset Microsoft.Extensions.Time.Testing.FakeTimeProvider.GetUtcNow();",
"Stage": "Experimental"
},
{
"Member": "void Microsoft.Extensions.Time.Testing.FakeTimeProvider.SetLocalTimeZone(System.TimeZoneInfo localTimeZone);",
"Stage": "Experimental"
},
{
"Member": "void Microsoft.Extensions.Time.Testing.FakeTimeProvider.SetUtcNow(System.DateTimeOffset value);",
"Stage": "Experimental"
},
{
"Member": "override string Microsoft.Extensions.Time.Testing.FakeTimeProvider.ToString();",
"Stage": "Experimental"
}
],
"Properties": [
{
"Member": "System.TimeSpan Microsoft.Extensions.Time.Testing.FakeTimeProvider.AutoAdvanceAmount { get; set; }",
"Stage": "Experimental"
},
{
"Member": "override System.TimeZoneInfo Microsoft.Extensions.Time.Testing.FakeTimeProvider.LocalTimeZone { get; }",
"Stage": "Experimental"
},
{
"Member": "System.DateTimeOffset Microsoft.Extensions.Time.Testing.FakeTimeProvider.Start { get; }",
"Stage": "Experimental"
},
{
"Member": "override long Microsoft.Extensions.Time.Testing.FakeTimeProvider.TimestampFrequency { get; }",
"Stage": "Experimental"
}
]
}
]
}