Skip to content

Commit

Permalink
[Generator] Provide a way to get all the types from the assembly. (#1…
Browse files Browse the repository at this point in the history
…9481)

Reduce the amount of work/logic in BT. The TypeManager has an all the
needed pieces to provide a API that contains all the types we are
interested in.

---------

Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
  • Loading branch information
mandel-macaque and GitHub Actions Autoformatter authored Nov 21, 2023
1 parent 67633dc commit 2b80159
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 29 deletions.
22 changes: 5 additions & 17 deletions src/bgen/BindingTouch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ int Main3 (string [] args)
"mscorlib"
);

if (!TryLoadApi (tmpass, out Assembly? api) || !TryLoadApi (baselibdll, out Assembly? baselib))
if (!TryLoadApi (tmpass, out Assembly? apiAssembly) || !TryLoadApi (baselibdll, out Assembly? baselib))
return 1;

attributeManager ??= new AttributeManager (this);
Expand All @@ -440,10 +440,10 @@ int Main3 (string [] args)
// Explicitly load our attribute library so that IKVM doesn't try (and fail) to find it.
universe.LoadFromAssemblyPath (GetAttributeLibraryPath ());

typeCache ??= new (universe, Frameworks, CurrentPlatform, api, universe.CoreAssembly, baselib, BindThirdPartyLibrary);
typeCache ??= new (universe, Frameworks, CurrentPlatform, apiAssembly, universe.CoreAssembly, baselib, BindThirdPartyLibrary);
typeManager ??= new (this);

foreach (var linkWith in AttributeManager.GetCustomAttributes<LinkWithAttribute> (api)) {
foreach (var linkWith in AttributeManager.GetCustomAttributes<LinkWithAttribute> (apiAssembly)) {
#if NET
if (string.IsNullOrEmpty (linkWith.LibraryName))
#else
Expand Down Expand Up @@ -479,26 +479,14 @@ int Main3 (string [] args)
}
}

var types = new List<Type> ();
var strong_dictionaries = new List<Type> ();
foreach (var t in api.GetTypes ()) {
if ((config.ProcessEnums && t.IsEnum) ||
AttributeManager.HasAttribute<BaseTypeAttribute> (t) ||
AttributeManager.HasAttribute<ProtocolAttribute> (t) ||
AttributeManager.HasAttribute<StaticAttribute> (t) ||
AttributeManager.HasAttribute<PartialAttribute> (t))
types.Add (t);
if (AttributeManager.HasAttribute<StrongDictionaryAttribute> (t))
strong_dictionaries.Add (t);
}

var api = TypeManager.ParseApi (apiAssembly, config.ProcessEnums);
namespaceCache ??= new NamespaceCache (
CurrentPlatform,
config.HelperClassNamespace ?? firstApiDefinitionName,
skipSystemDrawing
);

var g = new Generator (this, config.IsPublicMode, config.IsExternal, config.IsDebug, types.ToArray (), strong_dictionaries.ToArray ()) {
var g = new Generator (this, api, config.IsPublicMode, config.IsExternal, config.IsDebug) {
BaseDir = config.BindingFilesOutputDirectory ?? config.TemporaryFileDirectory,
ZeroCopyStrings = config.UseZeroCopy,
InlineSelectors = config.InlineSelectors ?? (CurrentPlatform != PlatformName.MacOSX),
Expand Down
22 changes: 10 additions & 12 deletions src/bgen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Nomenclator Nomenclator {
public string CoreServicesMap => CurrentPlatform.GetCoreServicesMap ();
public string PDFKitMap => CurrentPlatform.GetPDFKitMap ();

Type [] types, strong_dictionaries;
Api api;
bool debug;
bool external;
StreamWriter sw, m;
Expand Down Expand Up @@ -1273,14 +1273,13 @@ public ExportAttribute GetGetterExportAttribute (PropertyInfo pinfo)
return AttributeManager.GetCustomAttribute<ExportAttribute> (pinfo).ToGetter (pinfo);
}

public Generator (BindingTouch binding_touch, bool is_public_mode, bool external, bool debug, Type [] types, Type [] strong_dictionaries)
public Generator (BindingTouch binding_touch, Api api, bool is_public_mode, bool external, bool debug)
{
BindingTouch = binding_touch;
IsPublicMode = is_public_mode;
this.external = external;
this.debug = debug;
this.types = types;
this.strong_dictionaries = strong_dictionaries;
this.api = api;
basedir = ".";
NativeHandleType = binding_touch.IsDotNet ? "NativeHandle" : "IntPtr";
}
Expand Down Expand Up @@ -1314,10 +1313,9 @@ public void Go ()
send_methods ["IntPtr_objc_msgSendSuper_IntPtr"] = "IntPtr_objc_msgSendSuper_IntPtr";
}

Array.Sort (types, (a, b) => string.CompareOrdinal (a.FullName, b.FullName));
TypeManager.SetTypesThatMustAlwaysBeGloballyNamed (types);
TypeManager.SetTypesThatMustAlwaysBeGloballyNamed (api.Types);

foreach (Type t in types) {
foreach (Type t in api.Types) {
if (t.IsUnavailable (this))
continue;

Expand Down Expand Up @@ -1485,7 +1483,7 @@ public void Go ()
selectors [t] = tselectors.Distinct ();
}

foreach (Type t in types) {
foreach (Type t in api.Types) {
if (t.IsUnavailable (this))
continue;

Expand Down Expand Up @@ -1781,7 +1779,7 @@ void GenerateLibraryHandles ()
//
void GenerateStrongDictionaryTypes ()
{
foreach (var dictType in strong_dictionaries) {
foreach (var dictType in api.StrongDictionaries) {
if (dictType.IsUnavailable (this))
continue;
var sa = AttributeManager.GetCustomAttribute<StrongDictionaryAttribute> (dictType);
Expand Down Expand Up @@ -4712,7 +4710,7 @@ IEnumerable<PropertyInfo> SelectProtocolProperties (Type type, bool? @static = n
// If a type comes from the assembly with the api definition we're processing.
bool IsApiType (Type type)
{
return type.Assembly == types [0].Assembly;
return type.Assembly == api.Types [0].Assembly;
}

bool IsRequired (MemberInfo provider, Attribute [] attributes = null)
Expand Down Expand Up @@ -5511,7 +5509,7 @@ public void Generate (Type type)
continue;

string nonInterfaceName = protocolType.Name.Substring (1);
if (!types.Any (x => x.Name.Contains (nonInterfaceName)))
if (!api.Types.Any (x => x.Name.Contains (nonInterfaceName)))
continue;

if (is_category_class)
Expand Down Expand Up @@ -6607,7 +6605,7 @@ public void Generate (Type type)
//
// Copy delegates from the API files into the output if they were declared there
//
var rootAssembly = types [0].Assembly;
var rootAssembly = api.Types [0].Assembly;
foreach (var deltype in trampolines.Keys.OrderBy (d => d.Name, StringComparer.Ordinal)) {
if (deltype.Assembly != rootAssembly)
continue;
Expand Down
13 changes: 13 additions & 0 deletions src/bgen/Models/Api.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#nullable enable

using System;
using System.Reflection;

// contains all the types defined in the API to generate. This could have
// been a (Type [] Types, Type [] StrongDictionaries) but we have to keep
// backcompat before dotnet. records do work ;)
public record Api (Type [] Types, Type [] StrongDictionaries) {

public Type [] Types { get; } = Types;
public Type [] StrongDictionaries { get; } = StrongDictionaries;
}
25 changes: 25 additions & 0 deletions src/bgen/TypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Foundation;

#nullable enable

Expand Down Expand Up @@ -362,4 +363,28 @@ public bool IsDictionaryContainerType (Type t)
{
return t.IsSubclassOf (TypeCache.DictionaryContainerType) || (t.IsInterface && AttributeManager.HasAttribute<StrongDictionaryAttribute> (t));
}

public Api ParseApi (Assembly api, bool processEnums)
{
var types = new List<Type> ();
var strongDictionaries = new List<Type> ();

foreach (var t in api.GetTypes ()) {
if ((processEnums && t.IsEnum) ||
AttributeManager.HasAttribute<BaseTypeAttribute> (t) ||
AttributeManager.HasAttribute<ProtocolAttribute> (t) ||
AttributeManager.HasAttribute<StaticAttribute> (t) ||
AttributeManager.HasAttribute<PartialAttribute> (t))
// skip those types that are not available
types.Add (t);
if (AttributeManager.HasAttribute<StrongDictionaryAttribute> (t))
strongDictionaries.Add (t);
}

// we should sort the types based on the full name
var typesArray = types.ToArray ();
Array.Sort (typesArray, (a, b) => string.CompareOrdinal (a.FullName, b.FullName));

return new (typesArray, strongDictionaries.ToArray ());
}
}
1 change: 1 addition & 0 deletions src/generator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
<Compile Include="bgen\Extensions\PlatformNameExtensions.cs" />
<Compile Include="bgen\Extensions\StringExtensions.cs" />
<Compile Include="bgen\Extensions\TypeExtensions.cs" />
<Compile Include="bgen\Models\Api.cs" />
<Compile Include="bgen\Models\AsyncMethodInfo.cs" />
<Compile Include="bgen\Models\BindingTouchConfig.cs" />
<Compile Include="bgen\Models\MarshalInfo.cs" />
Expand Down

6 comments on commit 2b80159

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.