-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Check in simple end-to-end test for covariant returns. #46285
Merged
gafter
merged 9 commits into
dotnet:features/covariant-returns
from
gafter:covariant-returns-e2e1
Jul 28, 2020
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
5043b93
Check in simple end-to-end test for covariant returns.
35ce852
Get the end to end tests running
jaredpar 4bb2803
Add a conditional skip reason for covariant return support
a9a7664
Add a test that the runtime has required members.
82bb08c
Skip building dummy covariant return reference library when not needed.
5f44b3f
Merge branch 'features/covariant-returns' of https://github.com/dotne…
5f53ba1
Conditionally compile the covariant returns runtime tests to see if t…
03aee9f
Filter out the 5.0 tests
jaredpar 01be338
Change build to support `net5.0` TFs
jaredpar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
310 changes: 310 additions & 0 deletions
310
src/Compilers/CSharp/Test/Emit/Emit/CovariantReturnTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,310 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
#if NETCOREAPP | ||
|
||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.CodeAnalysis.CSharp.Test.Utilities; | ||
using Microsoft.CodeAnalysis.Test.Utilities; | ||
using Roslyn.Test.Utilities; | ||
using Xunit; | ||
|
||
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Emit | ||
{ | ||
public class CovariantReturnTests : EmitMetadataTestBase | ||
{ | ||
private static readonly MetadataReference CorelibraryWithCovariantReturnSupport; | ||
|
||
static CovariantReturnTests() | ||
{ | ||
if (new CovarantReturnRuntimeOnly().ShouldSkip) | ||
return; | ||
|
||
const string corLibraryCore = @" | ||
namespace System | ||
{ | ||
public class Array | ||
{ | ||
public static T[] Empty<T>() => throw null; | ||
} | ||
public class Console | ||
{ | ||
public static void WriteLine(string message) => throw null; | ||
} | ||
public class Attribute { } | ||
[Flags] | ||
public enum AttributeTargets | ||
{ | ||
Assembly = 0x1, | ||
Module = 0x2, | ||
Class = 0x4, | ||
Struct = 0x8, | ||
Enum = 0x10, | ||
Constructor = 0x20, | ||
Method = 0x40, | ||
Property = 0x80, | ||
Field = 0x100, | ||
Event = 0x200, | ||
Interface = 0x400, | ||
Parameter = 0x800, | ||
Delegate = 0x1000, | ||
ReturnValue = 0x2000, | ||
GenericParameter = 0x4000, | ||
All = 0x7FFF | ||
} | ||
[AttributeUsage(AttributeTargets.Class, Inherited = true)] | ||
public sealed class AttributeUsageAttribute : Attribute | ||
{ | ||
public AttributeUsageAttribute(AttributeTargets validOn) { } | ||
public bool AllowMultiple | ||
{ | ||
get => throw null; | ||
set { } | ||
} | ||
public bool Inherited | ||
{ | ||
get => throw null; | ||
set { } | ||
} | ||
public AttributeTargets ValidOn => throw null; | ||
} | ||
public struct Boolean { } | ||
public struct Byte { } | ||
public class Delegate | ||
{ | ||
public static Delegate CreateDelegate(Type type, object firstArgument, Reflection.MethodInfo method) => null; | ||
} | ||
public abstract class Enum : IComparable { } | ||
public class Exception | ||
{ | ||
public Exception(string message) => throw null; | ||
} | ||
public class FlagsAttribute : Attribute { } | ||
public delegate T Func<out T>(); | ||
public delegate U Func<in T, out U>(T arg); | ||
public interface IComparable { } | ||
public interface IDisposable | ||
{ | ||
void Dispose(); | ||
} | ||
public struct Int16 { } | ||
public struct Int32 { } | ||
public struct IntPtr { } | ||
public class MulticastDelegate : Delegate { } | ||
public struct Nullable<T> { } | ||
public class Object | ||
{ | ||
public virtual string ToString() => throw null; | ||
public virtual int GetHashCode() => throw null; | ||
public virtual bool Equals(object other) => throw null; | ||
} | ||
public sealed class ParamArrayAttribute : Attribute { } | ||
public struct RuntimeMethodHandle { } | ||
public struct RuntimeTypeHandle { } | ||
public class String : IComparable { | ||
public static String Empty = null; | ||
public override string ToString() => throw null; | ||
public static bool operator ==(string a, string b) => throw null; | ||
public static bool operator !=(string a, string b) => throw null; | ||
public override bool Equals(object other) => throw null; | ||
public override int GetHashCode() => throw null; | ||
} | ||
public class Type | ||
{ | ||
public Reflection.FieldInfo GetField(string name) => null; | ||
public static Type GetType(string name) => null; | ||
public static Type GetTypeFromHandle(RuntimeTypeHandle handle) => null; | ||
} | ||
public class ValueType { } | ||
public struct Void { } | ||
|
||
namespace Collections | ||
{ | ||
public interface IEnumerable | ||
{ | ||
IEnumerator GetEnumerator(); | ||
} | ||
public interface IEnumerator | ||
{ | ||
object Current | ||
{ | ||
get; | ||
} | ||
bool MoveNext(); | ||
void Reset(); | ||
} | ||
} | ||
namespace Collections.Generic | ||
{ | ||
public interface IEnumerable<out T> : IEnumerable | ||
{ | ||
new IEnumerator<T> GetEnumerator(); | ||
} | ||
public interface IEnumerator<out T> : IEnumerator, IDisposable | ||
{ | ||
new T Current | ||
{ | ||
get; | ||
} | ||
} | ||
} | ||
namespace Linq.Expressions | ||
{ | ||
public class Expression | ||
{ | ||
public static ParameterExpression Parameter(Type type) => throw null; | ||
public static ParameterExpression Parameter(Type type, string name) => throw null; | ||
public static MethodCallExpression Call(Expression instance, Reflection.MethodInfo method, params Expression[] arguments) => throw null; | ||
public static Expression<TDelegate> Lambda<TDelegate>(Expression body, params ParameterExpression[] parameters) => throw null; | ||
public static MemberExpression Property(Expression expression, Reflection.MethodInfo propertyAccessor) => throw null; | ||
public static ConstantExpression Constant(object value, Type type) => throw null; | ||
public static UnaryExpression Convert(Expression expression, Type type) => throw null; | ||
} | ||
public class ParameterExpression : Expression { } | ||
public class MethodCallExpression : Expression { } | ||
public abstract class LambdaExpression : Expression { } | ||
public class Expression<T> : LambdaExpression { } | ||
public class MemberExpression : Expression { } | ||
public class ConstantExpression : Expression { } | ||
public sealed class UnaryExpression : Expression { } | ||
} | ||
namespace Reflection | ||
{ | ||
public class AssemblyVersionAttribute : Attribute | ||
{ | ||
public AssemblyVersionAttribute(string version) { } | ||
} | ||
public class DefaultMemberAttribute : Attribute | ||
{ | ||
public DefaultMemberAttribute(string name) { } | ||
} | ||
public abstract class MemberInfo { } | ||
public abstract class MethodBase : MemberInfo | ||
{ | ||
public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle) => throw null; | ||
} | ||
public abstract class MethodInfo : MethodBase | ||
{ | ||
public virtual Delegate CreateDelegate(Type delegateType, object target) => throw null; | ||
} | ||
public abstract class FieldInfo : MemberInfo | ||
{ | ||
public abstract object GetValue(object obj); | ||
} | ||
} | ||
namespace Runtime.CompilerServices | ||
{ | ||
public static class RuntimeHelpers | ||
{ | ||
public static object GetObjectValue(object obj) => null; | ||
} | ||
} | ||
} | ||
"; | ||
const string corlibWithCovariantSupport = corLibraryCore + @" | ||
namespace System.Runtime.CompilerServices | ||
{ | ||
public static class RuntimeFeature | ||
{ | ||
public const string CovariantReturnsOfClasses = nameof(CovariantReturnsOfClasses); | ||
public const string DefaultImplementationsOfInterfaces = nameof(DefaultImplementationsOfInterfaces); | ||
} | ||
public sealed class PreserveBaseOverridesAttribute : Attribute { } | ||
} | ||
"; | ||
var compilation = CreateEmptyCompilation(new string[] { | ||
corlibWithCovariantSupport, | ||
@"[assembly: System.Reflection.AssemblyVersion(""4.0.0.0"")]" | ||
}, assemblyName: "mscorlib"); | ||
compilation.VerifyDiagnostics(); | ||
CorelibraryWithCovariantReturnSupport = compilation.EmitToImageReference(options: new CodeAnalysis.Emit.EmitOptions(runtimeMetadataVersion: "v5.1")); | ||
} | ||
|
||
private static CSharpCompilation CreateCovariantCompilation( | ||
string source, | ||
CSharpCompilationOptions options = null, | ||
IEnumerable<MetadataReference> references = null) | ||
{ | ||
Assert.NotNull(CorelibraryWithCovariantReturnSupport); | ||
references = (references == null) ? | ||
new[] { CorelibraryWithCovariantReturnSupport } : | ||
references.ToArray().Prepend(CorelibraryWithCovariantReturnSupport); | ||
return CreateEmptyCompilation( | ||
source, | ||
options: options, | ||
parseOptions: TestOptions.WithCovariantReturns, | ||
references: references); | ||
} | ||
|
||
[ConditionalFact(typeof(CovarantReturnRuntimeOnly))] | ||
public void SimpleCovariantReturnEndToEndTest() | ||
{ | ||
var source = @" | ||
using System; | ||
class Base | ||
{ | ||
public virtual object M() => ""Base.M""; | ||
} | ||
class Derived : Base | ||
{ | ||
public override string M() => ""Derived.M""; | ||
} | ||
class Program | ||
{ | ||
static void Main() | ||
{ | ||
Derived d = new Derived(); | ||
Base b = d; | ||
string s = d.M(); | ||
object o = b.M(); | ||
Console.WriteLine(s.ToString()); | ||
Console.WriteLine(o.ToString()); | ||
} | ||
} | ||
"; | ||
var compilation = CreateCovariantCompilation(source, options: TestOptions.DebugExe); | ||
compilation.VerifyDiagnostics(); | ||
var expectedOutput = | ||
@"Derived.M | ||
Derived.M"; | ||
CompileAndVerify(compilation, expectedOutput: expectedOutput, verify: Verification.Skipped); | ||
} | ||
|
||
[ConditionalFact(typeof(CovarantReturnRuntimeOnly))] | ||
public void CovariantRuntimeHasRequiredMembers() | ||
{ | ||
var source = @" | ||
using System; | ||
class Base | ||
{ | ||
public virtual object M() => ""Base.M""; | ||
} | ||
class Derived : Base | ||
{ | ||
public override string M() => ""Derived.M""; | ||
} | ||
class Program | ||
{ | ||
static void Main() | ||
{ | ||
var value = (string)Type.GetType(""System.Runtime.CompilerServices.RuntimeFeature"").GetField(""CovariantReturnsOfClasses"").GetValue(null); | ||
if (value != ""CovariantReturnsOfClasses"") | ||
throw new Exception(value.ToString()); | ||
|
||
var attr = Type.GetType(""System.Runtime.CompilerServices.PreserveBaseOverridesAttribute""); | ||
if (attr == null) | ||
throw new Exception(""missing System.Runtime.CompilerServices.PreserveBaseOverridesAttribute""); | ||
} | ||
} | ||
"; | ||
var compilation = CreateCovariantCompilation(source, options: TestOptions.DebugExe); | ||
compilation.VerifyDiagnostics(); | ||
var expectedOutput = @""; | ||
CompileAndVerify(compilation, expectedOutput: expectedOutput, verify: Verification.Skipped); | ||
} | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
<PropertyGroup> | ||
<OutputType>Library</OutputType> | ||
<RootNamespace>Microsoft.CodeAnalysis.CSharp.UnitTests</RootNamespace> | ||
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks> | ||
<TargetFrameworks>net5.0;net472</TargetFrameworks> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to confirm, we're intentionally keeping our other test projects targeting netcoreapp3.1? #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
<ItemGroup Label="Project References"> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: Covariant