Skip to content

Commit 5e12b4f

Browse files
layomiajoperezr
andauthored
Clean up DynamicDependencyAttribute usages (#38216)
* Add support for shared source in linker test code * Clean up DynamicDependencyAttribute usages * Clean up DynamicDependencyAttribute: review feedback + another test Co-authored-by: Jose Perez Rodriguez <joperezr@microsoft.com>
1 parent a87ebc5 commit 5e12b4f

13 files changed

Lines changed: 453 additions & 19 deletions

File tree

eng/testing/linker/trimmingTests.targets

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@
5757
<_projectSourceFile>%(TestConsoleApps.ProjectCompileItems)</_projectSourceFile>
5858
</PropertyGroup>
5959

60+
<ItemGroup>
61+
<_additionalProjectSourceFiles Include="%(TestConsoleApps.AdditionalSourceFiles)" />
62+
</ItemGroup>
63+
6064
<MakeDir Directories="$(_projectDir)" />
6165
<WriteLinesToFile File="$(_projectFile)"
6266
Lines="$([System.IO.File]::ReadAllText('$(ProjectTemplate)')
@@ -68,6 +72,9 @@
6872
Overwrite="true" />
6973
<Copy SourceFiles="$(_projectSourceFile)"
7074
DestinationFolder="$(_projectDir)" />
75+
<Copy SourceFiles="@(_additionalProjectSourceFiles)"
76+
DestinationFolder="$(_projectDir)"
77+
Condition="'@(_additionalProjectSourceFiles)' != ''" />
7178
<Message Text="Generated $(_projectFile)" />
7279
</Target>
7380

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeDescriptor.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ private TypeDescriptor()
8585
[EditorBrowsable(EditorBrowsableState.Advanced)]
8686
public static Type InterfaceType
8787
{
88-
// TODO: replace this with DynamicallyAccessedMembersAttribute (https://github.com/dotnet/runtime/issues/37837)
89-
[DynamicDependency("#ctor", typeof(TypeDescriptorInterface))]
88+
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
9089
get => typeof(TypeDescriptorInterface);
9190
}
9291

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.ComponentModel;
3+
4+
/// <summary>
5+
/// Tests that the System.ComponentModel.TypeDescriptor.InterfaceType
6+
/// property works as expected when used in a trimmed application.
7+
/// </summary>
8+
class Program
9+
{
10+
static int Main(string[] args)
11+
{
12+
Type type = TypeDescriptor.InterfaceType;
13+
14+
// Tests that the ctor for System.ComponentModel.TypeDescriptor+TypeDescriptorInterface is not trimmed out.
15+
object obj = Activator.CreateInstance(type);
16+
string expectedObjTypeNamePrefix = "System.ComponentModel.TypeDescriptor+TypeDescriptorInterface, System.ComponentModel.TypeConverter, Version=";
17+
18+
return obj != null && obj.GetType().AssemblyQualifiedName.StartsWith(expectedObjTypeNamePrefix)
19+
? 100
20+
: -1;
21+
}
22+
}

src/libraries/System.Data.Common/src/System/Data/SQLTypes/SqlXml.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ private static Func<Stream, XmlReaderSettings, XmlParserContext, XmlReader> Crea
128128

129129
private static MethodInfo CreateSqlReaderMethodInfo
130130
{
131-
[DynamicDependency("CreateSqlReader", typeof(System.Xml.XmlReader))]
132131
get
133132
{
134133
if (s_createSqlReaderMethodInfo == null)

src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/CallInstruction.Generated.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
using System.Collections.Generic;
66
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Dynamic;
89
using System.Dynamic.Utils;
910
using System.Reflection;
10-
using System.Diagnostics.CodeAnalysis;
1111
using System.Threading;
1212

1313
namespace System.Linq.Expressions.Interpreter
@@ -160,17 +160,7 @@ private static CallInstruction FastCreate<T0, T1>(MethodInfo target, ParameterIn
160160
#endif
161161

162162
#if FEATURE_DLG_INVOKE
163-
// TODO: replace these with DynamicallyAccessedMembersAttribute (https://github.com/dotnet/runtime/issues/37837)
164-
[DynamicDependency("#ctor", typeof(ActionCallInstruction))]
165-
[DynamicDependency("#ctor", typeof(ActionCallInstruction<>))]
166-
[DynamicDependency("#ctor", typeof(ActionCallInstruction<,>))]
167-
[DynamicDependency("#ctor", typeof(ActionCallInstruction<,,>))]
168-
[DynamicDependency("#ctor", typeof(ActionCallInstruction<,,,>))]
169-
[DynamicDependency("#ctor", typeof(FuncCallInstruction<>))]
170-
[DynamicDependency("#ctor", typeof(FuncCallInstruction<,>))]
171-
[DynamicDependency("#ctor", typeof(FuncCallInstruction<,,>))]
172-
[DynamicDependency("#ctor", typeof(FuncCallInstruction<,,,>))]
173-
[DynamicDependency("#ctor", typeof(FuncCallInstruction<,,,,>))]
163+
[return: DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes.PublicConstructors)]
174164
private static Type GetHelperType(MethodInfo info, Type[] arrTypes)
175165
{
176166
Type t;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using System.Linq.Expressions;
9+
10+
/// <summary>
11+
/// Tests that the System.Linq.Expressions.Interpreter.CallInstruction.GetHelperType
12+
/// method works as expected when used in a trimmed application.
13+
/// </summary>
14+
internal class Program
15+
{
16+
static int Main(string[] args)
17+
{
18+
for (int rank = 1; rank < 6; rank++)
19+
{
20+
Array arrayObj = Array.CreateInstance(typeof(string), Enumerable.Repeat(1, rank).ToArray());
21+
arrayObj.SetValue("solitary value", Enumerable.Repeat(0, rank).ToArray());
22+
ConstantExpression array = Expression.Constant(arrayObj);
23+
IEnumerable<DefaultExpression> indices = Enumerable.Repeat(Expression.Default(typeof(int)), rank);
24+
// This code path for the Compile call excercises the method being tested.
25+
Func<string> func = Expression.Lambda<Func<string>>(
26+
Expression.ArrayAccess(array, indices)).Compile(preferInterpretation: true);
27+
28+
if (func() != "solitary value")
29+
{
30+
return -1;
31+
}
32+
}
33+
34+
return 100;
35+
}
36+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project DefaultTargets="Build">
2+
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" />
3+
4+
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets))" />
5+
</Project>

src/libraries/System.Net.HttpListener/src/System/Net/Windows/CookieExtensions.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ internal static class CookieExtensions
1313
{
1414
private static Func<Cookie, string> s_toServerStringFunc;
1515

16-
[DynamicDependency("ToServerString", typeof(Cookie))]
1716
public static string ToServerString(this Cookie cookie)
1817
{
1918
s_toServerStringFunc ??= (Func<Cookie, string>)typeof(Cookie).GetMethod("ToServerString", BindingFlags.Instance | BindingFlags.NonPublic).CreateDelegate(typeof(Func<Cookie, string>));
@@ -23,7 +22,6 @@ public static string ToServerString(this Cookie cookie)
2322

2423
private static Func<Cookie, Cookie> s_cloneFunc;
2524

26-
[DynamicDependency("Clone", typeof(Cookie))]
2725
public static Cookie Clone(this Cookie cookie)
2826
{
2927
s_cloneFunc ??= (Func<Cookie, Cookie>)typeof(Cookie).GetMethod("Clone", BindingFlags.Instance | BindingFlags.NonPublic).CreateDelegate(typeof(Func<Cookie, Cookie>));
@@ -42,7 +40,6 @@ private enum CookieVariant
4240

4341
private static Func<Cookie, CookieVariant> s_getVariantFunc;
4442

45-
[DynamicDependency("get_Variant", typeof(Cookie))]
4643
public static bool IsRfc2965Variant(this Cookie cookie)
4744
{
4845
s_getVariantFunc ??= (Func<Cookie, CookieVariant>)typeof(Cookie).GetProperty("Variant", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true).CreateDelegate(typeof(Func<Cookie, CookieVariant>));
@@ -55,7 +52,6 @@ internal static class CookieCollectionExtensions
5552
{
5653
private static Func<CookieCollection, Cookie, bool, int> s_internalAddFunc;
5754

58-
[DynamicDependency("InternalAdd", typeof(CookieCollection))]
5955
public static int InternalAdd(this CookieCollection cookieCollection, Cookie cookie, bool isStrict)
6056
{
6157
s_internalAddFunc ??= (Func<CookieCollection, Cookie, bool, int>)typeof(CookieCollection).GetMethod("InternalAdd", BindingFlags.Instance | BindingFlags.NonPublic).CreateDelegate(typeof(Func<CookieCollection, Cookie, bool, int>));
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Net;
6+
using System.Threading.Tasks;
7+
8+
namespace CookieExtensionsTest
9+
{
10+
/// <summary>
11+
/// Tests that the System.Net.CookieExtensions.Clone()
12+
/// method works as expected when used in a trimmed application.
13+
/// </summary>
14+
internal class Program
15+
{
16+
static async Task<int> Main(string[] args)
17+
{
18+
var helper = new TestHelper();
19+
HttpListenerResponse response = await helper.GetResponse();
20+
var cookie = new Cookie("name", "value");
21+
response.SetCookie(cookie);
22+
23+
// Cookies are cloned.
24+
cookie.Value = "value3";
25+
if (response.Cookies[0].Value != "value")
26+
{
27+
return -1;
28+
}
29+
30+
return 100;
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)