Skip to content

Commit

Permalink
feat: Initial support to trimming
Browse files Browse the repository at this point in the history
  • Loading branch information
felipebz committed Dec 26, 2023
1 parent d1aecce commit c6f26a4
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 64 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Expand Up @@ -30,6 +30,9 @@ jobs:
- name: Build NuGet package
run: dotnet pack -c Release --no-build

- name: Build trimmed sample with NativeAOT
run: dotnet publish -c Release_12_2_1_3 -p:"Platform=x64;PublishAot=true" -r linux-x64

- name: Add NuGet source
run: dotnet nuget add source --username felipebz --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/felipebz/index.json"

Expand Down
7 changes: 4 additions & 3 deletions Ndapi/Metadata/NdapiMetaObject.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

using Ndapi.Core;
Expand All @@ -13,7 +14,7 @@ namespace Ndapi.Metadata;
public sealed class NdapiMetaObject
{
private static readonly Dictionary<Type, NdapiMetaObject> _cache = new();

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
private readonly Type _type;
private readonly Lazy<IEnumerable<NdapiMetaProperty>> _properties;

Expand Down Expand Up @@ -52,7 +53,7 @@ public sealed class NdapiMetaObject
/// </summary>
public IEnumerable<NdapiMetaProperty> ChildObjectProperties => AllProperties.Where(p => p.IsList);

private NdapiMetaObject(Type type)
private NdapiMetaObject([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type)
{
TypeName = type.Name;

Expand All @@ -68,7 +69,7 @@ private IEnumerable<NdapiMetaProperty> LoadProperties()
return properties.OrderBy(p => p.PropertyId).ToList();
}

internal static NdapiMetaObject GetOrCreate(Type type)
internal static NdapiMetaObject GetOrCreate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type)
{
if (_cache.TryGetValue(type, out var metaObject))
{
Expand Down
2 changes: 1 addition & 1 deletion Ndapi/Metadata/NdapiMetaProperty.cs
Expand Up @@ -97,7 +97,7 @@ internal static NdapiMetaProperty GetOrCreate(int propertyId, string name, bool
private Dictionary<int, string> LoadAllowedValues()
{
return AcceptConstants ?
Enum.GetValues(RawPropertyType).Cast<int>().ToDictionary(e => e, e => Enum.GetName(RawPropertyType, e)) :
Enum.GetValuesAsUnderlyingType(RawPropertyType).Cast<int>().ToDictionary(e => e, e => Enum.GetName(RawPropertyType, e)) :
new Dictionary<int, string>();
}

Expand Down
110 changes: 62 additions & 48 deletions Ndapi/Metadata/NdapiMetadata.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;

using Ndapi.Enums;
Expand All @@ -11,70 +12,83 @@ namespace Ndapi.Metadata;
/// </summary>
public static class NdapiMetadata
{
private static readonly Lazy<Dictionary<ObjectType, Type>> _objectTypeMapping = new(LoadObjectTypeMapping);

private static readonly IList<ObjectTypeMap> _objectTypeMapping = LoadObjectTypeMapping();

/// <summary>
/// Gets the Ndapi classes that represents a Forms API object.
/// </summary>
public static IEnumerable<Type> Classes => ObjectTypeMapping.Values;
public static IEnumerable<Type> Classes => _objectTypeMapping.Select(x => x.Type);

/// <summary>
/// Gets a dictionary containing the relation bettwen an <see cref="ObjectType"/> and a Ndapi class.
/// </summary>
public static Dictionary<ObjectType, Type> ObjectTypeMapping => _objectTypeMapping.Value;
//public static Dictionary<ObjectType, Type> ObjectTypeMapping => _objectTypeMapping.Value;

private static Dictionary<ObjectType, Type> LoadObjectTypeMapping() =>
new()
{
{ ObjectType.Alert, typeof(Alert) },
{ ObjectType.AttachedLibrary, typeof(AttachedLibrary) },
{ ObjectType.Block, typeof(Block) },
{ ObjectType.Canvas, typeof(Canvas) },
{ ObjectType.CompoundText, typeof(CompoundText) },
{ ObjectType.Coordinate, typeof(Coordinate) },
{ ObjectType.DataSourceArgument, typeof(DataSourceArgument) },
{ ObjectType.DataSourceColumn, typeof(DataSourceColumn) },
{ ObjectType.Editor, typeof(Editor) },
{ ObjectType.Font, typeof(Font) },
{ ObjectType.FormModule, typeof(FormModule) },
{ ObjectType.FormParameter, typeof(FormParameter) },
{ ObjectType.Graphics, typeof(Graphics) },
{ ObjectType.Item, typeof(Item) },
{ ObjectType.LibraryProgramUnit, typeof(LibraryProgramUnit) },
{ ObjectType.LibraryModule, typeof(LibraryModule) },
{ ObjectType.LOV, typeof(LOV) },
{ ObjectType.ColumnMapping, typeof(ColumnMapping) },
{ ObjectType.Menu, typeof(Menu) },
{ ObjectType.MenuItem, typeof(MenuItem) },
{ ObjectType.MenuModule, typeof(MenuModule) },
private static IList<ObjectTypeMap> LoadObjectTypeMapping() =>
[
new ObjectTypeMap(ObjectType.Alert, typeof(Alert)),
new ObjectTypeMap(ObjectType.AttachedLibrary, typeof(AttachedLibrary)),
new ObjectTypeMap(ObjectType.Block, typeof(Block)),
new ObjectTypeMap(ObjectType.Canvas, typeof(Canvas)),
new ObjectTypeMap(ObjectType.CompoundText, typeof(CompoundText)),
new ObjectTypeMap(ObjectType.Coordinate, typeof(Coordinate)),
new ObjectTypeMap(ObjectType.DataSourceArgument, typeof(DataSourceArgument)),
new ObjectTypeMap(ObjectType.DataSourceColumn, typeof(DataSourceColumn)),
new ObjectTypeMap(ObjectType.Editor, typeof(Editor)),
new ObjectTypeMap(ObjectType.Font, typeof(Font)),
new ObjectTypeMap(ObjectType.FormModule, typeof(FormModule)),
new ObjectTypeMap(ObjectType.FormParameter, typeof(FormParameter)),
new ObjectTypeMap(ObjectType.Graphics, typeof(Graphics)),
new ObjectTypeMap(ObjectType.Item, typeof(Item)),
new ObjectTypeMap(ObjectType.LibraryProgramUnit, typeof(LibraryProgramUnit)),
new ObjectTypeMap(ObjectType.LibraryModule, typeof(LibraryModule)),
new ObjectTypeMap(ObjectType.LOV, typeof(LOV)),
new ObjectTypeMap(ObjectType.ColumnMapping, typeof(ColumnMapping)),
new ObjectTypeMap(ObjectType.Menu, typeof(Menu)),
new ObjectTypeMap(ObjectType.MenuItem, typeof(MenuItem)),
new ObjectTypeMap(ObjectType.MenuModule, typeof(MenuModule)),
#if FORMS_6
{ ObjectType.MenuParameter, typeof(MenuParameter) },
new ObjectTypeMap(ObjectType.MenuParameter, typeof(MenuParameter)),
#endif
{ ObjectType.ObjectGroup, typeof(ObjectGroup) },
{ ObjectType.ObjectGroupChild, typeof(ObjectGroupChild) },
{ ObjectType.ObjectLibrary, typeof(ObjectLibrary) },
{ ObjectType.ObjectLibraryTab, typeof(ObjectLibraryTab) },
{ ObjectType.Point, typeof(Point) },
{ ObjectType.ProgramUnit, typeof(ProgramUnit) },
{ ObjectType.PropertyClass, typeof(PropertyClass) },
{ ObjectType.RadioButton, typeof(RadioButton) },
{ ObjectType.RecordGroup, typeof(RecordGroup) },
{ ObjectType.BlockRelation, typeof(BlockRelation) },
{ ObjectType.Report, typeof(Report) },
{ ObjectType.ColumnSpecification, typeof(RecordGroupColumn) },
{ ObjectType.TabPage, typeof(TabPage) },
{ ObjectType.TextSegment, typeof(TextSegment) },
{ ObjectType.Trigger, typeof(Trigger) },
{ ObjectType.VisualAttribute, typeof(VisualAttribute) },
{ ObjectType.Window, typeof(Window) }
};
new ObjectTypeMap(ObjectType.ObjectGroup, typeof(ObjectGroup)),
new ObjectTypeMap(ObjectType.ObjectGroupChild, typeof(ObjectGroupChild)),
new ObjectTypeMap(ObjectType.ObjectLibrary, typeof(ObjectLibrary)),
new ObjectTypeMap(ObjectType.ObjectLibraryTab, typeof(ObjectLibraryTab)),
new ObjectTypeMap(ObjectType.Point, typeof(Point)),
new ObjectTypeMap(ObjectType.ProgramUnit, typeof(ProgramUnit)),
new ObjectTypeMap(ObjectType.PropertyClass, typeof(PropertyClass)),
new ObjectTypeMap(ObjectType.RadioButton, typeof(RadioButton)),
new ObjectTypeMap(ObjectType.RecordGroup, typeof(RecordGroup)),
new ObjectTypeMap(ObjectType.BlockRelation, typeof(BlockRelation)),
new ObjectTypeMap(ObjectType.Report, typeof(Report)),
new ObjectTypeMap(ObjectType.ColumnSpecification, typeof(RecordGroupColumn)),
new ObjectTypeMap(ObjectType.TabPage, typeof(TabPage)),
new ObjectTypeMap(ObjectType.TextSegment, typeof(TextSegment)),
new ObjectTypeMap(ObjectType.Trigger, typeof(Trigger)),
new ObjectTypeMap(ObjectType.VisualAttribute, typeof(VisualAttribute)),
new ObjectTypeMap(ObjectType.Window, typeof(Window))
];

/// <summary>
/// Gets a <see cref="NdapiMetaObject"/> for the specified class.
/// </summary>
/// <param name="type">A Ndapi class.</param>
/// <returns>The meta object instance.</returns>
public static NdapiMetaObject GetMetaObjectFrom(Type type) => NdapiMetaObject.GetOrCreate(type);
public static NdapiMetaObject GetMetaObjectFrom([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type) => NdapiMetaObject.GetOrCreate(type);

internal static ObjectType GetObjectTypeFrom<T>() => _objectTypeMapping.Single(t => t.Type == typeof(T)).ObjectType;

[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
internal static Type GetTypeFrom(ObjectType type) => _objectTypeMapping.Single(t => t.ObjectType == type).Type;

private class ObjectTypeMap(
ObjectType objectType,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
Type type)
{
public ObjectType ObjectType { get; } = objectType;

internal static ObjectType GetObjectTypeFrom<T>() => ObjectTypeMapping.Single(t => t.Value == typeof(T)).Key;
public Type Type { [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] get; } = type;
}
}
3 changes: 1 addition & 2 deletions Ndapi/Ndapi.csproj
Expand Up @@ -14,8 +14,7 @@
<Version>13.0.0-alpha</Version>
<NoWarn>NU5128</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

<!--<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">true</IsTrimmable>-->
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Debug_6_0_8' ">
Expand Down
15 changes: 8 additions & 7 deletions Ndapi/NdapiObject.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text;

Expand Down Expand Up @@ -152,10 +153,10 @@ public bool IsSubclassed
/// </summary>
public IEnumerable<NdapiMetaProperty> MetaProperties => MetaObject.AllProperties;

internal T GetPrevious<T>() where T : NdapiObject =>
internal T GetPrevious<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>() where T : NdapiObject =>
GetObjectProperty<T>(NdapiConstants.D2FP_PREVIOUS);

internal T GetNext<T>() where T : NdapiObject =>
internal T GetNext<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>() where T : NdapiObject =>
GetObjectProperty<T>(NdapiConstants.D2FP_NEXT);

/// <summary>
Expand Down Expand Up @@ -252,7 +253,7 @@ public void SetBooleanProperty(int property, bool value)
/// </summary>
/// <param name="property">Property id.</param>
/// <returns>The property value.</returns>
public T GetObjectProperty<T>(int property) where T : NdapiObject
public T GetObjectProperty<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(int property) where T : NdapiObject
{
var status = NativeMethods.d2fobgo_GetObjProp(NdapiContext.GetContext(), _handle, property, out var handle);
Ensure.Success(status);
Expand All @@ -276,7 +277,7 @@ public void SetBooleanProperty(int property, bool value)
/// </summary>
/// <param name="property">Property id.</param>
/// <returns>List of child objects.</returns>
public NdapiObjectList<T> GetObjectList<T>(int property) where T : NdapiObject
public NdapiObjectList<T> GetObjectList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(int property) where T : NdapiObject
{
return new NdapiObjectList<T>(this, property);
}
Expand Down Expand Up @@ -453,7 +454,7 @@ public virtual void Destroy()
Ensure.Success(status);
}

internal static T Create<T>(ObjectSafeHandle handle) where T : NdapiObject
internal static T Create<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(ObjectSafeHandle handle) where T : NdapiObject
{
var objectType = typeof(T);
if (objectType == typeof(NdapiObject))
Expand All @@ -466,7 +467,7 @@ public virtual void Destroy()
return null;
}

objectType = NdapiMetadata.ObjectTypeMapping[type];
objectType = NdapiMetadata.GetTypeFrom(type);
}

var instance = Activator.CreateInstance(objectType,
Expand Down Expand Up @@ -511,7 +512,7 @@ public void Dispose()
/// <summary>
/// Represents a generic object.
/// </summary>
public abstract class NdapiObject<T> : NdapiObject where T : NdapiObject
public abstract class NdapiObject<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T> : NdapiObject where T : NdapiObject
{
internal NdapiObject() { }
internal NdapiObject(ObjectType type) : base(type) { }
Expand Down
3 changes: 2 additions & 1 deletion Ndapi/NdapiObjectList.cs
@@ -1,14 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

using Ndapi.Core;
using Ndapi.Enums;
using Ndapi.Metadata;

namespace Ndapi;

public class NdapiObjectList<T> : IEnumerable<T> where T : NdapiObject
public class NdapiObjectList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T> : IEnumerable<T> where T : NdapiObject
{
private readonly NdapiObject _ndapiObject;
private readonly int _property;
Expand Down
6 changes: 4 additions & 2 deletions Ndapi/ObjectLibraryTab.cs
@@ -1,4 +1,6 @@
using Ndapi.Core;
using System.Diagnostics.CodeAnalysis;

using Ndapi.Core;
using Ndapi.Core.Handles;
using Ndapi.Enums;

Expand Down Expand Up @@ -73,7 +75,7 @@ public NdapiObject GetObjectByPosition(int position)
/// <param name="obj">Object to add to library tab.</param>
/// <param name="replace">Should replace the existing object.</param>
/// <returns>A copy of the original object.</returns>
public T AddObject<T>(T obj, bool replace = false) where T : NdapiObject
public T AddObject<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(T obj, bool replace = false) where T : NdapiObject
{
var status = NativeMethods.d2folbao_AddObj(NdapiContext.GetContext(), ObjectLibrary._handle, _handle, obj._handle, out var handle, replace);
Ensure.Success(status);
Expand Down

0 comments on commit c6f26a4

Please sign in to comment.