Skip to content

Commit

Permalink
Remove net20 and net45 targets from Roslyn (#59705)
Browse files Browse the repository at this point in the history
The remote debugger removed their references to our `net20` and `net45` components in favor of using our `netstandard2.0` versions. This allows us to delete our `net20` and `net45` assets which removes some unneeded code and build infra 

PR validation: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/381691
  • Loading branch information
jaredpar authored Feb 23, 2022
1 parent 1995735 commit 372e6ef
Show file tree
Hide file tree
Showing 21 changed files with 3 additions and 401 deletions.
24 changes: 0 additions & 24 deletions Roslyn.sln
Original file line number Diff line number Diff line change
Expand Up @@ -220,20 +220,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.Tasks.CodeA
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "BasicResultProvider", "src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\BasicResultProvider.shproj", "{3140FE61-0856-4367-9AA3-8081B9A80E35}"
EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "BasicResultProvider.NetFX20", "src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\NetFX20\BasicResultProvider.NetFX20.vbproj", "{76242A2D-2600-49DD-8C15-FEA07ECB1842}"
EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.CodeAnalysis.VisualBasic.ResultProvider", "src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\Portable\Microsoft.CodeAnalysis.VisualBasic.ResultProvider.vbproj", "{76242A2D-2600-49DD-8C15-FEA07ECB1843}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CSharpResultProvider", "src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.shproj", "{3140FE61-0856-4367-9AA3-8081B9A80E36}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpResultProvider.NetFX20", "src\ExpressionEvaluator\CSharp\Source\ResultProvider\NetFX20\CSharpResultProvider.NetFX20.csproj", "{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.CSharp.ResultProvider", "src\ExpressionEvaluator\CSharp\Source\ResultProvider\Portable\Microsoft.CodeAnalysis.CSharp.ResultProvider.csproj", "{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ResultProvider", "src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.shproj", "{BB3CA047-5D00-48D4-B7D3-233C1265C065}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ResultProvider.NetFX20", "src\ExpressionEvaluator\Core\Source\ResultProvider\NetFX20\ResultProvider.NetFX20.csproj", "{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.ResultProvider", "src\ExpressionEvaluator\Core\Source\ResultProvider\Portable\Microsoft.CodeAnalysis.ResultProvider.csproj", "{FA0E905D-EC46-466D-B7B2-3B5557F9428C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vbc", "src\Compilers\VisualBasic\vbc\vbc.csproj", "{E58EE9D7-1239-4961-A0C1-F9EC3952C4C1}"
Expand Down Expand Up @@ -540,7 +534,6 @@ Global
src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5
src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.projitems*{60db272a-21c9-4e8d-9803-ff4e132392c8}*SharedItemsImports = 5
src\Workspaces\SharedUtilitiesAndExtensions\Compiler\CSharp\CSharpCompilerExtensions.projitems*{699fea05-aea7-403d-827e-53cf4e826955}*SharedItemsImports = 13
src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\BasicResultProvider.projitems*{76242a2d-2600-49dd-8c15-fea07ecb1842}*SharedItemsImports = 5
src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\BasicResultProvider.projitems*{76242a2d-2600-49dd-8c15-fea07ecb1843}*SharedItemsImports = 5
src\Analyzers\Core\Analyzers\Analyzers.projitems*{76e96966-4780-4040-8197-bde2879516f4}*SharedItemsImports = 13
src\Compilers\Core\CommandLine\CommandLine.projitems*{7ad4fe65-9a30-41a6-8004-aa8f89bcb7f3}*SharedItemsImports = 5
Expand All @@ -562,8 +555,6 @@ Global
src\Compilers\Core\CommandLine\CommandLine.projitems*{ad6f474e-e6d4-4217-91f3-b7af1be31ccc}*SharedItemsImports = 13
src\Compilers\CSharp\CSharpAnalyzerDriver\CSharpAnalyzerDriver.projitems*{b501a547-c911-4a05-ac6e-274a50dff30e}*SharedItemsImports = 5
src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.projitems*{bb3ca047-5d00-48d4-b7d3-233c1265c065}*SharedItemsImports = 13
src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.projitems*{bedc5a4a-809e-4017-9cfd-6c8d4e1847f0}*SharedItemsImports = 5
src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.projitems*{bf9dac1e-3a5e-4dc3-bb44-9a64e0d4e9d3}*SharedItemsImports = 5
src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.projitems*{bf9dac1e-3a5e-4dc3-bb44-9a64e0d4e9d4}*SharedItemsImports = 5
src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{c1930979-c824-496b-a630-70f5369a636f}*SharedItemsImports = 13
src\Workspaces\SharedUtilitiesAndExtensions\Compiler\VisualBasic\VisualBasicCompilerExtensions.projitems*{cec0dce7-8d52-45c3-9295-fc7b16bd2451}*SharedItemsImports = 13
Expand Down Expand Up @@ -912,26 +903,14 @@ Global
{1DFEA9C5-973C-4179-9B1B-0F32288E1EF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DFEA9C5-973C-4179-9B1B-0F32288E1EF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DFEA9C5-973C-4179-9B1B-0F32288E1EF2}.Release|Any CPU.Build.0 = Release|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1842}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1842}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1842}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1842}.Release|Any CPU.Build.0 = Release|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1843}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1843}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76242A2D-2600-49DD-8C15-FEA07ECB1843}.Release|Any CPU.Build.0 = Release|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Release|Any CPU.Build.0 = Release|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Release|Any CPU.Build.0 = Release|Any CPU
{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Release|Any CPU.Build.0 = Release|Any CPU
{FA0E905D-EC46-466D-B7B2-3B5557F9428C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA0E905D-EC46-466D-B7B2-3B5557F9428C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA0E905D-EC46-466D-B7B2-3B5557F9428C}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -1400,13 +1379,10 @@ Global
{FCFA8808-A1B6-48CC-A1EA-0B8CA8AEDA8E} = {32A48625-F0AD-419D-828B-A50BDABA38EA}
{1DFEA9C5-973C-4179-9B1B-0F32288E1EF2} = {A41D1B99-F489-4C43-BBDF-96D61B19A6B9}
{3140FE61-0856-4367-9AA3-8081B9A80E35} = {151F6994-AEB3-4B12-B746-2ACFF26C7BBB}
{76242A2D-2600-49DD-8C15-FEA07ECB1842} = {151F6994-AEB3-4B12-B746-2ACFF26C7BBB}
{76242A2D-2600-49DD-8C15-FEA07ECB1843} = {151F6994-AEB3-4B12-B746-2ACFF26C7BBB}
{3140FE61-0856-4367-9AA3-8081B9A80E36} = {913A4C08-898E-49C7-9692-0EF9DC56CF6E}
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3} = {913A4C08-898E-49C7-9692-0EF9DC56CF6E}
{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4} = {913A4C08-898E-49C7-9692-0EF9DC56CF6E}
{BB3CA047-5D00-48D4-B7D3-233C1265C065} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6}
{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6}
{FA0E905D-EC46-466D-B7B2-3B5557F9428C} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6}
{E58EE9D7-1239-4961-A0C1-F9EC3952C4C1} = {C65C6143-BED3-46E6-869E-9F0BE6E84C37}
{6FD1CC3E-6A99-4736-9B8D-757992DDE75D} = {38940C5F-97FD-4B2A-B2CD-C4E4EF601B05}
Expand Down
1 change: 0 additions & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@
<MicrosoftNETFrameworkReferenceAssembliesnet20Version>1.0.0</MicrosoftNETFrameworkReferenceAssembliesnet20Version>
<jnm2ReferenceAssembliesnet35Version>1.0.1</jnm2ReferenceAssembliesnet35Version>
<MicrosoftNETCoreTestHostVersion>1.1.0</MicrosoftNETCoreTestHostVersion>
<MicrosoftNetFX20Version>1.0.3</MicrosoftNetFX20Version>
<MicrosoftNETFrameworkReferenceAssembliesVersion>1.0.0</MicrosoftNETFrameworkReferenceAssembliesVersion>
<MicrosoftNetSdkVersion>2.0.0-alpha-20170405-2</MicrosoftNetSdkVersion>
<MicrosoftNuGetBuildTasksVersion>0.1.0</MicrosoftNuGetBuildTasksVersion>
Expand Down
19 changes: 0 additions & 19 deletions eng/targets/Imports.targets
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,6 @@
<NoWarn>$(NoWarn);Nullable</NoWarn>
</PropertyGroup>

<ItemGroup Condition="'$(Language)' == 'CSharp' and '$(TargetFramework)' == 'net20'">
<_ExplicitReference Include="$(FrameworkPathOverride)\mscorlib.dll" />
</ItemGroup>

<!--
If the project targets Framework 2.0 reference assemblies provided by Microsoft.NetFramework.ReferenceAssemblies nuget package.
Use the latest Framework toolset to build, but set msbuild properties below
so to avoid 4.5 specific artifacts to be added to the compilation (references, attributes).
-->
<PropertyGroup Condition="'$(TargetFramework)' == 'net20'">
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<NoStdLib>true</NoStdLib>
<ResGenExecuteAsTool>false</ResGenExecuteAsTool>
<GenerateResourceMSBuildRuntime>CurrentRuntime</GenerateResourceMSBuildRuntime>

<!-- Bypass a check in msbuild that .NET Framework 3.5 is installed on the machine when targeting .NET < 4.0 -->
<BypassFrameworkInstallChecks>true</BypassFrameworkInstallChecks>
</PropertyGroup>

<!--
Do not copy dependencies to the output directory of a library project, unless it's a unit test project.
-->
Expand Down
2 changes: 0 additions & 2 deletions eng/targets/Settings.props
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Diagnostics" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'net20'">
<Import Include="System.Linq" />
</ItemGroup>
<PropertyGroup>
Expand Down
8 changes: 0 additions & 8 deletions src/Compilers/Core/Portable/CaseInsensitiveComparison.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ public override int Compare(string? str1, string? str2)
return str1.Length - str2.Length;
}

#if !NET20
public int Compare(ReadOnlySpan<char> str1, ReadOnlySpan<char> str2)
{
int len = Math.Min(str1.Length, str2.Length);
Expand All @@ -133,7 +132,6 @@ public int Compare(ReadOnlySpan<char> str1, ReadOnlySpan<char> str2)
// return the smaller string, or 0 if they are equal in length
return str1.Length - str2.Length;
}
#endif

private static bool AreEqualLowerUnicode(char c1, char c2)
{
Expand Down Expand Up @@ -168,7 +166,6 @@ public override bool Equals(string? str1, string? str2)
return true;
}

#if !NET20
public bool Equals(ReadOnlySpan<char> str1, ReadOnlySpan<char> str2)
{
if (str1.Length != str2.Length)
Expand All @@ -186,7 +183,6 @@ public bool Equals(ReadOnlySpan<char> str1, ReadOnlySpan<char> str2)

return true;
}
#endif

public static bool EndsWith(string value, string possibleEnd)
{
Expand Down Expand Up @@ -293,7 +289,6 @@ public override int GetHashCode(string str)
/// </remarks>
public static bool Equals(string left, string right) => s_comparer.Equals(left, right);

#if !NET20
/// <summary>
/// Determines if two strings are equal according to Unicode rules for case-insensitive
/// identifier comparison (lower-case mapping).
Expand All @@ -305,7 +300,6 @@ public override int GetHashCode(string str)
/// These are also the rules used for VB identifier comparison.
/// </remarks>
public static bool Equals(ReadOnlySpan<char> left, ReadOnlySpan<char> right) => s_comparer.Equals(left, right);
#endif

/// <summary>
/// Determines if the string 'value' end with string 'possibleEnd'.
Expand Down Expand Up @@ -335,7 +329,6 @@ public override int GetHashCode(string str)
/// </remarks>
public static int Compare(string left, string right) => s_comparer.Compare(left, right);

#if !NET20
/// <summary>
/// Compares two strings according to the Unicode rules for case-insensitive
/// identifier comparison (lower-case mapping).
Expand All @@ -347,7 +340,6 @@ public override int GetHashCode(string str)
/// These are also the rules used for VB identifier comparison.
/// </remarks>
public static int Compare(ReadOnlySpan<char> left, ReadOnlySpan<char> right) => s_comparer.Compare(left, right);
#endif

/// <summary>
/// Gets a case-insensitive hash code for Unicode identifiers.
Expand Down
12 changes: 1 addition & 11 deletions src/Compilers/Core/Portable/DiaSymReader/SymUnmanagedFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ internal static string DiaSymReaderModuleName

private delegate void NativeFactory(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object instance);

#if !NET20
private static readonly Lazy<Func<string, string>> s_lazyGetEnvironmentVariable = new Lazy<Func<string, string>>(() =>
{
try
Expand All @@ -80,18 +79,13 @@ internal static string DiaSymReaderModuleName
return null;
});
#endif

// internal for testing
internal static string GetEnvironmentVariable(string name)
{
try
{
#if NET20
return Environment.GetEnvironmentVariable(name);
#else
return s_lazyGetEnvironmentVariable.Value?.Invoke(name);
#endif
}
catch
{
Expand Down Expand Up @@ -122,7 +116,7 @@ private static object TryLoadFromAlternativePath(Guid clsid, string factoryName)
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}

#if NET20 || NETSTANDARD1_1
#if NETSTANDARD1_1
var creator = (NativeFactory)Marshal.GetDelegateForFunctionPointer(createAddress, typeof(NativeFactory));
#else
var creator = Marshal.GetDelegateForFunctionPointer<NativeFactory>(createAddress);
Expand All @@ -144,11 +138,7 @@ private static Type GetComTypeType(ref Type lazyType, Guid clsid)
{
if (lazyType == null)
{
#if NET20
lazyType = Type.GetTypeFromCLSID(clsid);
#else
lazyType = Marshal.GetTypeFromCLSID(clsid);
#endif
}

return lazyType;
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/Core/Portable/InternalUtilities/Debug.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static void AssertNotNull<T>([NotNull] T value)
[Conditional("DEBUG")]
internal static void AssertOrFailFast([DoesNotReturnIf(false)] bool condition, string? message = null)
{
#if NET20 || NETSTANDARD1_3
#if NETSTANDARD1_3
Debug.Assert(condition);
#else
if (!condition)
Expand Down
4 changes: 0 additions & 4 deletions src/Compilers/Core/Portable/InternalUtilities/FailFast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ internal static void OnFatalException(Exception exception)
Debugger.Break();
}

#if !NET20
// don't fail fast with an aggregate exception that is masking true exception
if (exception is AggregateException aggregate && aggregate.InnerExceptions.Count == 1)
{
exception = aggregate.InnerExceptions[0];
}

#endif
DumpStackTrace(exception: exception);

Environment.FailFast(exception.ToString(), exception);
Expand Down Expand Up @@ -78,11 +76,9 @@ internal static void DumpStackTrace(Exception? exception = null, string? message
}
}

#if !NET20
Console.WriteLine("Stack trace of handler");
var stackTrace = new StackTrace();
Console.WriteLine(stackTrace.ToString());
#endif

Console.Out.Flush();
}
Expand Down
14 changes: 0 additions & 14 deletions src/Compilers/Core/Portable/InternalUtilities/FatalError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
using System.Threading;
using Roslyn.Utilities;

#if NET20
// Some APIs referenced by documentation comments are not available on .NET Framework 2.0.
#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved
#endif

namespace Microsoft.CodeAnalysis.ErrorReporting
{
internal static class FatalError
Expand Down Expand Up @@ -57,11 +52,6 @@ public static void OverwriteHandler(ErrorReporterHandler? value)
s_handler = value;
}

// In the result provider, we aren't copying our handler to somewhere else, so we don't
// need this method. It's too much of a challenge to shared code to work in
// old versions of the runtime since APIs changed over time.
#if !NET20

/// <summary>
/// Copies the handler in this instance to the linked copy of this type in this other assembly.
/// </summary>
Expand All @@ -85,8 +75,6 @@ public static void CopyHandlerTo(Assembly assembly)
}
}

#endif

/// <summary>
/// Use in an exception filter to report an error without catching the exception.
/// The error is reported by calling <see cref="Handler"/>.
Expand Down Expand Up @@ -241,12 +229,10 @@ private static void Report(Exception exception, ErrorSeverity severity = ErrorSe
return;
}

#if !NET20
if (exception is AggregateException aggregate && aggregate.InnerExceptions.Count == 1 && aggregate.InnerExceptions[0].Data[s_reportedMarker] != null)
{
return;
}
#endif

if (!exception.Data.IsReadOnly)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Compilers/Core/Portable/InternalUtilities/RoslynString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ internal static class RoslynString
public static bool IsNullOrEmpty([NotNullWhen(returnValue: false)] string? value)
=> string.IsNullOrEmpty(value);

#if !NET20
/// <inheritdoc cref="string.IsNullOrWhiteSpace(string)"/>
public static bool IsNullOrWhiteSpace([NotNullWhen(returnValue: false)] string? value)
=> string.IsNullOrWhiteSpace(value);
#endif
}
}
4 changes: 0 additions & 4 deletions src/Dependencies/PooledObjects/ObjectPool`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@

namespace Microsoft.CodeAnalysis.PooledObjects
{
#if NET20
internal delegate TReturn Func<TArg, TReturn>(TArg arg);
#endif

/// <summary>
/// Generic implementation of object pooling pattern with predefined pool size limit. The main
/// purpose is that limited number of frequently used objects can be kept in the pool for
Expand Down

This file was deleted.

Loading

0 comments on commit 372e6ef

Please sign in to comment.