Skip to content

Commit c32af89

Browse files
mattleibowmarek-safar
authored andcommitted
[mono-api-tools] Make the tools work as libraries (#9793)
Right now, the set of mono-api-tools only works as console apps. This PR will make them work as normal dlls so they can be consumed by other apps and libraries. They will still work as .exes, so nothing visibly changes for existing users. The motivation for this is for some build process or third party tool to take an assembly and generate an .xml doc from it. Since the writer is in-memory, the tool can then parse the .xml and do whatever it needs to. The same goes for the diff tools - if the diff happens in-memory, then the tool can process it without having to save and then load from the file system. ## Libraries - [x] mono-api-info -> `Mono.ApiTools.ApiInfo` - [x] mono-api-diff -> `Mono.ApiTools.ApiDiff` - [x] mono-api-html -> `Mono.ApiTools.ApiDiffFormatted` ## Major changes - the existing `Driver` classes are now just thin wrappers to parse the args and pass it on to the generators - the "options" are now abstracted into config classes to avoid methods with numerous parameters - the APIs have new support for reading assembly and info `Stream`s instead of just file paths - added compiler flags to control the namespace and type visibility to make the library APIs nicer - added compiler flag to remove the `Driver` class and `Mono.Options` dependencies - the mono-api-info tool has some more options to allow it to run on libraries, and ignore dependencies that it cannot find - this makes it easier to use so that the entire dependency chain does not have to be loaded just to output the current assembly API ## Compiler defines - `EXCLUDE_DRIVER` will remove the console entry point and remove the dependency of Mono.Options - `USE_MONO_API_TOOLS_NAMESPACE` will switch the namespace to `Mono.ApiTools` so that libraries can have a nice API - `USE_INTERNAL_VISIBILITY` will make any non-essential, `public` APIs turn `internal` ## Review points - are there any variables/fields that are still static? - are there any exposed types/members that need to be hidden? - are the new names for the APIs and config classes OK? - are my whitespaces according to the guidelines? - did I go horribly wrong?
1 parent 58efe94 commit c32af89

22 files changed

+812
-404
lines changed

mcs/tools/corcompare/AssemblyResolver.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,22 @@
3232

3333
using Mono.Cecil;
3434

35-
namespace GuiCompare {
35+
namespace Mono.ApiTools {
3636

37-
public class AssemblyResolver : DefaultAssemblyResolver {
37+
class AssemblyResolver : DefaultAssemblyResolver {
3838

3939
public AssemblyDefinition ResolveFile (string file)
4040
{
41-
return ProcessFile (file);
41+
AddSearchDirectory (Path.GetDirectoryName (file));
42+
var assembly = AssemblyDefinition.ReadAssembly (file, new ReaderParameters { AssemblyResolver = this, InMemory = true });
43+
RegisterAssembly (assembly);
44+
45+
return assembly;
4246
}
4347

44-
AssemblyDefinition ProcessFile (string file)
48+
public AssemblyDefinition ResolveStream (Stream stream)
4549
{
46-
AddSearchDirectory (Path.GetDirectoryName (file));
47-
var assembly = AssemblyDefinition.ReadAssembly (file, new ReaderParameters { AssemblyResolver = this, InMemory = true });
50+
var assembly = AssemblyDefinition.ReadAssembly (stream, new ReaderParameters { AssemblyResolver = this, InMemory = true });
4851
RegisterAssembly (assembly);
4952

5053
return assembly;

mcs/tools/corcompare/Util.cs

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,57 @@
33
using System.Text;
44
using Mono.Cecil;
55

6-
using GuiCompare;
6+
namespace Mono.ApiTools {
77

8-
namespace CorCompare {
8+
class TypeHelper {
99

10-
static class TypeHelper {
10+
public TypeHelper (bool ignoreResolutionErrors, bool ignoreInheritedInterfaces)
11+
{
12+
IgnoreResolutionErrors = ignoreResolutionErrors;
13+
IgnoreInheritedInterfaces = ignoreInheritedInterfaces;
14+
}
15+
16+
public bool IgnoreResolutionErrors { get; }
17+
18+
public bool IgnoreInheritedInterfaces { get; }
1119

12-
public static AssemblyResolver Resolver = new AssemblyResolver ();
20+
public AssemblyResolver Resolver { get; } = new AssemblyResolver();
1321

14-
internal static bool IsPublic (TypeReference typeref)
22+
internal bool TryResolve (CustomAttribute attribute)
23+
{
24+
if (attribute == null)
25+
throw new ArgumentNullException (nameof (attribute));
26+
27+
try {
28+
var has = attribute.HasProperties;
29+
return true;
30+
} catch (AssemblyResolutionException) when (IgnoreResolutionErrors) {
31+
return false;
32+
}
33+
}
34+
35+
internal bool IsPublic (TypeReference typeref)
1536
{
1637
if (typeref == null)
1738
throw new ArgumentNullException ("typeref");
1839

19-
TypeDefinition td = typeref.Resolve ();
20-
if (td == null)
21-
return false;
40+
try {
41+
var td = typeref.Resolve ();
42+
if (td == null)
43+
return false;
2244

23-
return td.IsPublic;
45+
return td.IsPublic || (td.IsNestedPublic && IsPublic (td.DeclaringType));
46+
} catch (AssemblyResolutionException) when (IgnoreResolutionErrors) {
47+
return true;
48+
}
2449
}
2550

26-
internal static bool IsDelegate (TypeReference typeref)
51+
internal bool IsDelegate (TypeReference typeref)
2752
{
2853
return IsDerivedFrom (typeref, "System.MulticastDelegate");
2954
}
3055

31-
internal static bool IsDerivedFrom (TypeReference type, string derivedFrom)
56+
internal bool IsDerivedFrom (TypeReference type, string derivedFrom)
3257
{
3358
bool first = true;
3459
foreach (var def in WalkHierarchy (type)) {
@@ -44,52 +69,71 @@ internal static bool IsDerivedFrom (TypeReference type, string derivedFrom)
4469
return false;
4570
}
4671

47-
internal static IEnumerable<TypeDefinition> WalkHierarchy (TypeReference type)
72+
internal IEnumerable<TypeDefinition> WalkHierarchy (TypeReference type)
4873
{
4974
for (var def = type.Resolve (); def != null; def = GetBaseType (def))
5075
yield return def;
5176
}
5277

53-
internal static IEnumerable<TypeReference> GetInterfaces (TypeReference type)
78+
internal IEnumerable<TypeReference> GetInterfaces (TypeReference type)
5479
{
5580
var ifaces = new Dictionary<string, TypeReference> ();
5681

57-
foreach (var def in WalkHierarchy (type))
82+
foreach (var def in WalkHierarchy (type)) {
5883
foreach (var iface in def.Interfaces)
5984
ifaces [iface.InterfaceType.FullName] = iface.InterfaceType;
85+
if (IgnoreInheritedInterfaces)
86+
break;
87+
}
6088

6189
return ifaces.Values;
6290
}
6391

64-
internal static TypeDefinition GetBaseType (TypeDefinition child)
92+
internal TypeDefinition GetBaseType (TypeDefinition child)
6593
{
6694
if (child.BaseType == null)
6795
return null;
6896

69-
return child.BaseType.Resolve ();
97+
try {
98+
return child.BaseType.Resolve ();
99+
} catch (AssemblyResolutionException) when (IgnoreResolutionErrors) {
100+
return null;
101+
}
102+
}
103+
104+
internal MethodDefinition GetMethod (MethodReference method)
105+
{
106+
if (method == null)
107+
throw new ArgumentNullException (nameof (method));
108+
109+
try {
110+
return method.Resolve ();
111+
} catch (AssemblyResolutionException) when (IgnoreResolutionErrors) {
112+
return null;
113+
}
70114
}
71115

72-
internal static bool IsPublic (CustomAttribute att)
116+
internal bool IsPublic (CustomAttribute att)
73117
{
74118
return IsPublic (att.AttributeType);
75119
}
76120

77-
internal static string GetFullName (CustomAttribute att)
121+
internal string GetFullName (CustomAttribute att)
78122
{
79123
return att.AttributeType.FullName;
80124
}
81125

82-
internal static TypeDefinition GetTypeDefinition (CustomAttribute att)
126+
internal TypeDefinition GetTypeDefinition (CustomAttribute att)
83127
{
84128
return att.AttributeType.Resolve ();
85129
}
86130

87-
static bool IsOverride (MethodDefinition method)
131+
bool IsOverride (MethodDefinition method)
88132
{
89133
return method.IsVirtual && !method.IsNewSlot;
90134
}
91135

92-
public static MethodDefinition GetBaseMethodInTypeHierarchy (MethodDefinition method)
136+
public MethodDefinition GetBaseMethodInTypeHierarchy (MethodDefinition method)
93137
{
94138
if (!IsOverride (method))
95139
return method;
@@ -106,7 +150,7 @@ public static MethodDefinition GetBaseMethodInTypeHierarchy (MethodDefinition me
106150
return method;
107151
}
108152

109-
static MethodDefinition TryMatchMethod (TypeDefinition type, MethodDefinition method)
153+
MethodDefinition TryMatchMethod (TypeDefinition type, MethodDefinition method)
110154
{
111155
if (!type.HasMethods)
112156
return null;
@@ -118,7 +162,7 @@ static MethodDefinition TryMatchMethod (TypeDefinition type, MethodDefinition me
118162
return null;
119163
}
120164

121-
static bool MethodMatch (MethodDefinition candidate, MethodDefinition method)
165+
bool MethodMatch (MethodDefinition candidate, MethodDefinition method)
122166
{
123167
if (!candidate.IsVirtual)
124168
return false;
@@ -139,15 +183,15 @@ static bool MethodMatch (MethodDefinition candidate, MethodDefinition method)
139183
return true;
140184
}
141185

142-
public static bool TypeMatch (IModifierType a, IModifierType b)
186+
public bool TypeMatch (IModifierType a, IModifierType b)
143187
{
144188
if (!TypeMatch (a.ModifierType, b.ModifierType))
145189
return false;
146190

147191
return TypeMatch (a.ElementType, b.ElementType);
148192
}
149193

150-
public static bool TypeMatch (TypeSpecification a, TypeSpecification b)
194+
public bool TypeMatch (TypeSpecification a, TypeSpecification b)
151195
{
152196
if (a is GenericInstanceType)
153197
return TypeMatch ((GenericInstanceType) a, (GenericInstanceType) b);
@@ -158,7 +202,7 @@ public static bool TypeMatch (TypeSpecification a, TypeSpecification b)
158202
return TypeMatch (a.ElementType, b.ElementType);
159203
}
160204

161-
public static bool TypeMatch (GenericInstanceType a, GenericInstanceType b)
205+
public bool TypeMatch (GenericInstanceType a, GenericInstanceType b)
162206
{
163207
if (!TypeMatch (a.ElementType, b.ElementType))
164208
return false;
@@ -176,7 +220,7 @@ public static bool TypeMatch (GenericInstanceType a, GenericInstanceType b)
176220
return true;
177221
}
178222

179-
public static bool TypeMatch (TypeReference a, TypeReference b)
223+
public bool TypeMatch (TypeReference a, TypeReference b)
180224
{
181225
if (a is GenericParameter)
182226
return true;

mcs/tools/corcompare/WellFormedXmlWriter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
using System.Collections;
1212
using System.Xml;
1313

14-
namespace CorCompare {
14+
namespace Mono.ApiTools {
1515

16-
public class WellFormedXmlWriter : DefaultXmlWriter
16+
class WellFormedXmlWriter : DefaultXmlWriter
1717
{
1818
public static bool IsInvalid (int ch)
1919
{
@@ -110,7 +110,7 @@ public override void WriteChars (char [] text, int idx, int length)
110110

111111
}
112112

113-
public class DefaultXmlWriter : XmlWriter
113+
class DefaultXmlWriter : XmlWriter
114114
{
115115
XmlWriter writer;
116116

0 commit comments

Comments
 (0)