Skip to content

Commit 655ae9b

Browse files
authored
Merge pull request ststeiger#293 from Marv51/trimmable
Make PdfSharpCore trimmable
2 parents 1ab9add + 0732ba1 commit 655ae9b

11 files changed

+281
-8
lines changed

PdfSharpCore.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1818
EndProject
1919
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfSharpCore.Test", "PdfSharpCore.Test\PdfSharpCore.Test.csproj", "{A862C0CE-C095-459C-A32B-8FCDD15A93BF}"
2020
EndProject
21+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp", "SampleApp\SampleApp.csproj", "{E2F17280-6C54-4711-AF1C-3286D2C45526}"
22+
EndProject
2123
Global
2224
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2325
Debug|Any CPU = Debug|Any CPU
@@ -44,6 +46,10 @@ Global
4446
{A862C0CE-C095-459C-A32B-8FCDD15A93BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
4547
{A862C0CE-C095-459C-A32B-8FCDD15A93BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
4648
{A862C0CE-C095-459C-A32B-8FCDD15A93BF}.Release|Any CPU.Build.0 = Release|Any CPU
49+
{E2F17280-6C54-4711-AF1C-3286D2C45526}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50+
{E2F17280-6C54-4711-AF1C-3286D2C45526}.Debug|Any CPU.Build.0 = Debug|Any CPU
51+
{E2F17280-6C54-4711-AF1C-3286D2C45526}.Release|Any CPU.ActiveCfg = Release|Any CPU
52+
{E2F17280-6C54-4711-AF1C-3286D2C45526}.Release|Any CPU.Build.0 = Release|Any CPU
4753
EndGlobalSection
4854
GlobalSection(SolutionProperties) = preSolution
4955
HideSolutionNode = FALSE
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Included in .net 5 and later
2+
#if !NET5_0_OR_GREATER
3+
// Licensed to the .NET Foundation under one or more agreements.
4+
// The .NET Foundation licenses this file to you under the MIT license.
5+
6+
namespace System.Diagnostics.CodeAnalysis
7+
{
8+
/// <summary>
9+
/// Specifies the types of members that are dynamically accessed.
10+
///
11+
/// This enumeration has a <see cref="FlagsAttribute"/> attribute that allows a
12+
/// bitwise combination of its member values.
13+
/// </summary>
14+
[Flags]
15+
#if SYSTEM_PRIVATE_CORELIB
16+
public
17+
#else
18+
internal
19+
#endif
20+
enum DynamicallyAccessedMemberTypes
21+
{
22+
/// <summary>
23+
/// Specifies no members.
24+
/// </summary>
25+
None = 0,
26+
27+
/// <summary>
28+
/// Specifies the default, parameterless public constructor.
29+
/// </summary>
30+
PublicParameterlessConstructor = 0x0001,
31+
32+
/// <summary>
33+
/// Specifies all public constructors.
34+
/// </summary>
35+
PublicConstructors = 0x0002 | PublicParameterlessConstructor,
36+
37+
/// <summary>
38+
/// Specifies all non-public constructors.
39+
/// </summary>
40+
NonPublicConstructors = 0x0004,
41+
42+
/// <summary>
43+
/// Specifies all public methods.
44+
/// </summary>
45+
PublicMethods = 0x0008,
46+
47+
/// <summary>
48+
/// Specifies all non-public methods.
49+
/// </summary>
50+
NonPublicMethods = 0x0010,
51+
52+
/// <summary>
53+
/// Specifies all public fields.
54+
/// </summary>
55+
PublicFields = 0x0020,
56+
57+
/// <summary>
58+
/// Specifies all non-public fields.
59+
/// </summary>
60+
NonPublicFields = 0x0040,
61+
62+
/// <summary>
63+
/// Specifies all public nested types.
64+
/// </summary>
65+
PublicNestedTypes = 0x0080,
66+
67+
/// <summary>
68+
/// Specifies all non-public nested types.
69+
/// </summary>
70+
NonPublicNestedTypes = 0x0100,
71+
72+
/// <summary>
73+
/// Specifies all public properties.
74+
/// </summary>
75+
PublicProperties = 0x0200,
76+
77+
/// <summary>
78+
/// Specifies all non-public properties.
79+
/// </summary>
80+
NonPublicProperties = 0x0400,
81+
82+
/// <summary>
83+
/// Specifies all public events.
84+
/// </summary>
85+
PublicEvents = 0x0800,
86+
87+
/// <summary>
88+
/// Specifies all non-public events.
89+
/// </summary>
90+
NonPublicEvents = 0x1000,
91+
92+
/// <summary>
93+
/// Specifies all interfaces implemented by the type.
94+
/// </summary>
95+
Interfaces = 0x2000,
96+
97+
/// <summary>
98+
/// Specifies all members.
99+
/// </summary>
100+
All = ~None
101+
}
102+
}
103+
#endif
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Included in .net 5 and later
2+
#if !NET5_0_OR_GREATER
3+
// Licensed to the .NET Foundation under one or more agreements.
4+
// The .NET Foundation licenses this file to you under the MIT license.
5+
6+
namespace System.Diagnostics.CodeAnalysis
7+
{
8+
/// <summary>
9+
/// Indicates that certain members on a specified <see cref="Type"/> are accessed dynamically,
10+
/// for example through <see cref="System.Reflection"/>.
11+
/// </summary>
12+
/// <remarks>
13+
/// This allows tools to understand which members are being accessed during the execution
14+
/// of a program.
15+
///
16+
/// This attribute is valid on members whose type is <see cref="Type"/> or <see cref="string"/>.
17+
///
18+
/// When this attribute is applied to a location of type <see cref="string"/>, the assumption is
19+
/// that the string represents a fully qualified type name.
20+
///
21+
/// When this attribute is applied to a class, interface, or struct, the members specified
22+
/// can be accessed dynamically on <see cref="Type"/> instances returned from calling
23+
/// <see cref="object.GetType"/> on instances of that class, interface, or struct.
24+
///
25+
/// If the attribute is applied to a method it's treated as a special case and it implies
26+
/// the attribute should be applied to the "this" parameter of the method. As such the attribute
27+
/// should only be used on instance methods of types assignable to System.Type (or string, but no methods
28+
/// will use it there).
29+
/// </remarks>
30+
[AttributeUsage(
31+
AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
32+
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method |
33+
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct,
34+
Inherited = false)]
35+
#if SYSTEM_PRIVATE_CORELIB
36+
public
37+
#else
38+
internal
39+
#endif
40+
sealed class DynamicallyAccessedMembersAttribute : Attribute
41+
{
42+
/// <summary>
43+
/// Initializes a new instance of the <see cref="DynamicallyAccessedMembersAttribute"/> class
44+
/// with the specified member types.
45+
/// </summary>
46+
/// <param name="memberTypes">The types of members dynamically accessed.</param>
47+
public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
48+
{
49+
MemberTypes = memberTypes;
50+
}
51+
52+
/// <summary>
53+
/// Gets the <see cref="DynamicallyAccessedMemberTypes"/> which specifies the type
54+
/// of members dynamically accessed.
55+
/// </summary>
56+
public DynamicallyAccessedMemberTypes MemberTypes { get; }
57+
}
58+
}
59+
#endif

PdfSharpCore/Pdf/EntryInfoAttribute.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#endregion
2929

3030
using System;
31+
using System.Diagnostics.CodeAnalysis;
3132

3233
namespace PdfSharpCore.Pdf
3334
{
@@ -90,14 +91,16 @@ public KeyInfoAttribute(string version, KeyType keyType)
9091
KeyType = keyType;
9192
}
9293

93-
public KeyInfoAttribute(KeyType keyType, Type objectType)
94+
public KeyInfoAttribute(KeyType keyType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
95+
Type objectType)
9496
{
9597
//_version = version;
9698
KeyType = keyType;
9799
_objectType = objectType;
98100
}
99101

100-
public KeyInfoAttribute(string version, KeyType keyType, Type objectType)
102+
public KeyInfoAttribute(string version, KeyType keyType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
103+
Type objectType)
101104
{
102105
//_version = version;
103106
KeyType = keyType;
@@ -118,11 +121,14 @@ public KeyType KeyType
118121
}
119122
KeyType _entryType;
120123

124+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
121125
public Type ObjectType
122126
{
123127
get { return _objectType; }
124128
set { _objectType = value; }
125129
}
130+
131+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
126132
Type _objectType;
127133

128134
public string FixedValue

PdfSharpCore/Pdf/KeysBase.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#endregion
2929

3030
using System;
31+
using System.Diagnostics.CodeAnalysis;
3132

3233
namespace PdfSharpCore.Pdf
3334
{
@@ -36,7 +37,7 @@ namespace PdfSharpCore.Pdf
3637
/// </summary>
3738
public class KeysBase
3839
{
39-
internal static DictionaryMeta CreateMeta(Type type)
40+
internal static DictionaryMeta CreateMeta([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type type)
4041
{
4142
return new DictionaryMeta(type);
4243
}

PdfSharpCore/Pdf/KeysMeta.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
using System.Diagnostics;
3232
using System.Collections.Generic;
3333
using System.Reflection;
34+
using System.Diagnostics.CodeAnalysis;
3435

3536
namespace PdfSharpCore.Pdf
3637
{
@@ -85,11 +86,13 @@ public string FixedValue
8586
}
8687
readonly string _fixedValue;
8788

89+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
8890
public Type ObjectType
8991
{
9092
get { return _objectType; }
9193
set { _objectType = value; }
9294
}
95+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
9396
Type _objectType;
9497

9598
public bool CanBeIndirect
@@ -100,6 +103,7 @@ public bool CanBeIndirect
100103
/// <summary>
101104
/// Returns the type of the object to be created as value for the described key.
102105
/// </summary>
106+
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
103107
public Type GetValueType()
104108
{
105109
Type type = _objectType;
@@ -180,8 +184,21 @@ public Type GetValueType()
180184
/// </summary>
181185
internal class DictionaryMeta
182186
{
183-
public DictionaryMeta(Type type)
187+
public DictionaryMeta([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type type)
184188
{
189+
#if NET5_0_OR_GREATER
190+
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
191+
foreach (FieldInfo field in fields)
192+
{
193+
var attributes = field.GetCustomAttributes<KeyInfoAttribute>(false);
194+
foreach (var attribute in attributes)
195+
{
196+
KeyDescriptor descriptor = new KeyDescriptor(attribute);
197+
descriptor.KeyValue = (string)field.GetValue(null);
198+
_keyDescriptors[descriptor.KeyValue] = descriptor;
199+
}
200+
}
201+
#else
185202
// Rewritten for WinRT.
186203
CollectKeyDescriptors(type);
187204
//var fields = type.GetRuntimeFields(); // does not work
@@ -196,8 +213,10 @@ public DictionaryMeta(Type type)
196213
// _keyDescriptors[descriptor.KeyValue] = descriptor;
197214
// }
198215
//}
216+
#endif
199217
}
200218

219+
#if !NET5_0_OR_GREATER
201220
// Background: The function GetRuntimeFields gets constant fields only for the specified type,
202221
// not for its base types. So we have to walk recursively through base classes.
203222
// The docmentation says full trust for the immediate caller is required for property BaseClass.
@@ -220,6 +239,7 @@ void CollectKeyDescriptors(Type type)
220239
if (type != typeof(object) && type != typeof(PdfObject))
221240
CollectKeyDescriptors(type);
222241
}
242+
#endif
223243

224244
/// <summary>
225245
/// Gets the KeyDescriptor of the specified key, or null if no such descriptor exits.

PdfSharpCore/Pdf/PdfDictionary.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
using PdfSharpCore.Pdf.Filters;
4040
using PdfSharpCore.Pdf.Advanced;
4141
using PdfSharpCore.Pdf.Internal;
42+
using System.Diagnostics.CodeAnalysis;
4243

4344
namespace PdfSharpCore.Pdf
4445
{
@@ -947,6 +948,7 @@ public PdfItem GetValue(string key)
947948
/// <summary>
948949
/// Returns the type of the object to be created as value of the specified key.
949950
/// </summary>
951+
[return:DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
950952
Type GetValueType(string key) // TODO: move to PdfObject
951953
{
952954
Type type = null;
@@ -964,7 +966,7 @@ Type GetValueType(string key) // TODO: move to PdfObject
964966
return type;
965967
}
966968

967-
PdfArray CreateArray(Type type, PdfArray oldArray)
969+
PdfArray CreateArray([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]Type type, PdfArray oldArray)
968970
{
969971
// Rewritten WinRT style.
970972
PdfArray array = null;
@@ -1003,7 +1005,8 @@ PdfArray CreateArray(Type type, PdfArray oldArray)
10031005
return array;
10041006
}
10051007

1006-
PdfDictionary CreateDictionary(Type type, PdfDictionary oldDictionary)
1008+
PdfDictionary CreateDictionary([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
1009+
Type type, PdfDictionary oldDictionary)
10071010
{
10081011
// Rewritten WinRT style.
10091012
PdfDictionary dict = null;
@@ -1040,7 +1043,7 @@ PdfDictionary CreateDictionary(Type type, PdfDictionary oldDictionary)
10401043
return dict;
10411044
}
10421045

1043-
PdfItem CreateValue(Type type, PdfDictionary oldValue)
1046+
PdfItem CreateValue([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]Type type, PdfDictionary oldValue)
10441047
{
10451048

10461049
// Rewritten WinRT style.

PdfSharpCore/PdfSharpCore.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ PdfSharpCore is a partial port of PdfSharp.Xamarin for .NET Core Additionally Mi
1313
<RepositoryUrl>https://github.com/ststeiger/PdfSharpCore</RepositoryUrl>
1414
<PackageReleaseNotes>PdfSharpCore is a partial port of PdfSharp.Xamarin for .NET Core Additionally MigraDoc has been ported as well (from version 1.32)</PackageReleaseNotes>
1515
<PackageTags>NuggetV1.0.0 (8ea343d5898342a563b9d4df2d67e27aaea9ac01)</PackageTags>
16-
<summary>PdfSharp for .NET Core</summary>
16+
<summary>PdfSharp for .NET Core</summary>
17+
<IsTrimmable>true</IsTrimmable>
18+
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
1719
</PropertyGroup>
1820

1921
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

0 commit comments

Comments
 (0)