Welcome to mirror list, hosted at ThFree Co, Russian Federation.

DynamicDependencyLookupStep.cs « Linker.Steps « linker « src - github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 16536bb509789e85601800dcc99cf47eaf9da925 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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.

using System;
using System.Diagnostics;
using Mono.Cecil;
using System.Diagnostics.CodeAnalysis;

#nullable enable

namespace Mono.Linker.Steps
{
	public class DynamicDependencyLookupStep : LoadReferencesStep
	{
		protected override void ProcessAssembly (AssemblyDefinition assembly)
		{
			if (Annotations.GetAction (assembly) == AssemblyAction.Skip)
				return;

			var module = assembly.MainModule;

			foreach (var type in module.Types) {
				ProcessType (type);
			}
		}

		void ProcessType (TypeDefinition type)
		{
			if (type.HasMethods) {
				foreach (var method in type.GetMethods ()) {
					var methodDefinition = method.Resolve ();
					if (methodDefinition?.HasCustomAttributes != true)
						continue;

					ProcessDynamicDependencyAttributes (methodDefinition);
				}
			}

			if (type.HasFields) {
				foreach (var field in type.Fields) {
					var fieldDefinition = field.Resolve ();
					if (fieldDefinition?.HasCustomAttributes != true)
						continue;

					ProcessDynamicDependencyAttributes (fieldDefinition);
				}
			}

			if (type.HasNestedTypes) {
				foreach (var nestedType in type.NestedTypes) {
					ProcessType (nestedType);
				}
			}
		}

		void ProcessDynamicDependencyAttributes (IMemberDefinition member)
		{
			Debug.Assert (member is MethodDefinition || member is FieldDefinition);

			foreach (var ca in member.CustomAttributes) {
				if (!IsPreserveDependencyAttribute (ca.AttributeType))
					continue;
#if FEATURE_ILLINK
				Context.LogWarning ($"'PreserveDependencyAttribute' is deprecated. Use 'DynamicDependencyAttribute' instead.", 2033, member);
#endif
				if (ca.ConstructorArguments.Count != 3)
					continue;

				if (!(ca.ConstructorArguments[2].Value is string assemblyName))
					continue;

				var assembly = Context.Resolve (new AssemblyNameReference (assemblyName, new Version ()));
				if (assembly == null)
					continue;
				ProcessReferences (assembly);
			}

			var dynamicDependencies = Context.Annotations.GetLinkerAttributes<DynamicDependency> (member);
			Debug.Assert (dynamicDependencies != null);

			foreach (var dynamicDependency in dynamicDependencies) {
				if (dynamicDependency.AssemblyName == null)
					continue;

				var assembly = Context.Resolve (new AssemblyNameReference (dynamicDependency.AssemblyName, new Version ()));
				if (assembly == null) {
					Context.LogWarning ($"Unresolved assembly '{dynamicDependency.AssemblyName}' in 'DynamicDependencyAttribute'", 2035, member);
					continue;
				}

				ProcessReferences (assembly);
			}
		}

		public static bool IsPreserveDependencyAttribute (TypeReference tr)
		{
			return tr.Name == "PreserveDependencyAttribute" && tr.Namespace == "System.Runtime.CompilerServices";
		}
	}
}