Skip to content

Commit

Permalink
Update AutoKeyAccessor
Browse files Browse the repository at this point in the history
  • Loading branch information
feast107 committed Jun 4, 2024
1 parent 485fdc4 commit 49617e8
Show file tree
Hide file tree
Showing 18 changed files with 311 additions and 63 deletions.
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,38 @@ Auto generate anything you may want
{
public static void Fun(this int i) => StaticClass.Fun(i); // call original method
}
///
```

+ #### `[AutoKeyAccessor]`:

Auto generate `object this[string key]` accessor

```csharp
[AutoKeyAccessor]
class Foo
{
public bool Property { get; set; }
}

/// <generated>
partial class Foo
{
public object? this[string key]
{
get
{
switch (key)
{
case nameof(this.Property): return this.Property;
}
return null;
};
set
{
switch (key)
{
case nameof(this.Property): this.Property = (bool)value; break;
}
};
}
}
```
15 changes: 14 additions & 1 deletion src/Antelcat.AutoGen.Native/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@

Console.WriteLine(new DemoClass().GetType());

Console.WriteLine(typeof(DemoClass));
Console.WriteLine(typeof(DemoClass));


public struct A
{
public object? this[string key]
{
get => "";
set
{

}
}
}
18 changes: 0 additions & 18 deletions src/Antelcat.AutoGen.Sample/Extensions/MapExtension.cs

This file was deleted.

17 changes: 17 additions & 0 deletions src/Antelcat.AutoGen.Sample/Extensions/Mapping/MapExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Antelcat.AutoGen.ComponentModel.Mapping;
using Antelcat.AutoGen.Sample.Models.Mapping;

namespace Antelcat.AutoGen.Sample.Extensions.Mapping;

public static partial class MapExtension
{
[AutoMap(Extra = [nameof(Test)])]
public static partial Antelcat.AutoGen.Sample.Models.Mapping.SampleEntity ToEntity(this SampleDto dto);


public static void Test()
{
new SampleDto("").ToEntity();
}
}

33 changes: 33 additions & 0 deletions src/Antelcat.AutoGen.Sample/Models/Accessor/INeedAccessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Antelcat.AutoGen.ComponentModel;

namespace Antelcat.AutoGen.Sample.Models.Accessor;

[AutoKeyAccessor]
public partial interface INeedAccessor
{
public string A => nameof(A);
}

public class NeedBase
{
public virtual int D { get; set; }
}

[AutoKeyAccessor(includeField: true, Get = false)]
public partial class NeedAccessor : NeedBase, INeedAccessor
{
public int B { get; set; }

public override int D { get; set; }

private int d;
}

[AutoKeyAccessor]
public partial struct StructAlsoNeedAccessor
{
public byte C
{
set { }
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System.IO;
using Antelcat.AutoGen.ComponentModel.Mapping;

namespace Antelcat.AutoGen.Sample.Models;
namespace Antelcat.AutoGen.Sample.Models.Mapping;

public class FileDescriptor
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Antelcat.AutoGen.Sample.Models;
namespace Antelcat.AutoGen.Sample.Models.Mapping;

public class SampleDto(string other)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Antelcat.AutoGen.ComponentModel.Diagnostic;
using Antelcat.AutoGen.ComponentModel.Mapping;
using Antelcat.AutoGen.Sample.Models;

namespace Antelcat;
namespace Antelcat.AutoGen.Sample.Models.Mapping;

public class EntityBase
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\AutoDeconstructIndexableAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\AutoExtendForAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\AutoFilePathAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\AutoKeyAccessor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\AutoStringToAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Diagnostic\AutoReport.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ComponentModel\Diagnostic\AutoWatchAttribute.cs" />
Expand Down
35 changes: 35 additions & 0 deletions src/Antelcat.AutoGen.Shared/ComponentModel/AutoKeyAccessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using Antelcat.AutoGen.ComponentModel.Abstractions;

namespace Antelcat.AutoGen.ComponentModel;

/// <summary>
/// Auto generate key accessor for the target type, default to properties
/// </summary>
/// <param name="includeInherited">include inherited members</param>
/// <param name="includeField">include fields</param>
/// <param name="accessibility">this property accessibility</param>
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)]
public class AutoKeyAccessor(
bool includeInherited = true,
bool includeField = false,
Accessibility accessibility = Accessibility.Public)
: AutoGenAttribute
{
internal readonly Accessibility Accessibility = accessibility;
internal readonly bool IncludeInherited = includeInherited;
internal readonly bool IncludeField = includeField;

/// <summary>
/// accessor can get, default true
/// </summary>
public bool Get { get; set; } = true;

/// <summary>
/// accessor can set, default true
/// </summary>
public bool Set { get; set; } = true;

public string[]? Ignores { get; set; }

}
53 changes: 42 additions & 11 deletions src/Antelcat.AutoGen.SourceGenerators/General.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ internal static class General
internal const string Namespace = $"{nameof(Antelcat)}.{nameof(AutoGen)}";

internal const string ComponentModel = $"{Namespace}.{nameof(ComponentModel)}";

internal const string GlobalNamespace = "<global namespace>";

internal static string Global(Type? type) => $"{global}{type?.FullName}";
internal static string Nullable(Type? type) => type?.IsValueType == true ? string.Empty : "?";
internal static string Generic(string? name) => name != null ? $"<{name}>" : string.Empty;
Expand Down Expand Up @@ -169,20 +172,48 @@ internal static MethodDeclarationSyntax FullQualifiedPartialMethod(this MethodDe
internal static ClassDeclarationSyntax PartialClass(this ClassDeclarationSyntax syntax) =>
ClassDeclaration(syntax.Identifier).WithModifiers(SyntaxTokenList.Create(Token(SyntaxKind.PartialKeyword)));

internal static ClassDeclarationSyntax PartialClassDeclaration(this INamedTypeSymbol @class) =>
ClassDeclaration(@class.Name + (!@class.IsGenericType
? string.Empty
: $"<{string.Join(",", @class.TypeParameters.Select(x => x.Name))}>"))
internal static TypeDeclarationSyntax PartialTypeDeclaration(this INamedTypeSymbol @class)
{
var identifier = @class.Name + (!@class.IsGenericType
? string.Empty
: $"<{string.Join(",", @class.TypeParameters.Select(x => x.Name))}>");
return (@class.TypeKind switch
{
TypeKind.Class => (TypeDeclarationSyntax)ClassDeclaration(identifier)
.AddModifiers(Token(SyntaxKind.PartialKeyword)),
TypeKind.Interface => InterfaceDeclaration(identifier)
.AddModifiers(Token(SyntaxKind.PartialKeyword)),
TypeKind.Structure or TypeKind.Struct => StructDeclaration(identifier)
.AddModifiers(Token(SyntaxKind.PartialKeyword)),
_ => throw new ArgumentException()
})
.WithModifiers(SyntaxTokenList.Create(Token(SyntaxKind.PartialKeyword)));
}

internal static CompilationUnitSyntax AddPartialClass(this CompilationUnitSyntax compilationUnit,
internal static CompilationUnitSyntax AddPartialType(this CompilationUnitSyntax compilationUnit,
INamedTypeSymbol @class,
Func<ClassDeclarationSyntax, ClassDeclarationSyntax> map) =>
compilationUnit
.AddMembers(NamespaceDeclaration(IdentifierName(@class.ContainingNamespace.ToDisplayString()))
.WithLeadingTrivia(Header)
.AddMembers(map(@class.PartialClassDeclaration())));

Func<TypeDeclarationSyntax, TypeDeclarationSyntax> map)
{
var ret = map(@class.PartialTypeDeclaration());
var aggregate = ret as MemberDeclarationSyntax;
var parent = @class.ContainingType;
while (parent != null)
{
aggregate = parent.PartialTypeDeclaration().AddMembers(aggregate);
if (parent.ContainingType != null) parent = parent.ContainingType;
else break;
}

var namespaceStr = @class.ContainingNamespace.ToDisplayString();
if (namespaceStr is not GlobalNamespace)
{
aggregate = NamespaceDeclaration(IdentifierName(@class.ContainingNamespace.ToDisplayString()))
.WithLeadingTrivia(Header)
.AddMembers(aggregate);
}
return compilationUnit.AddMembers(aggregate);
}

public static TypeParameterConstraintClauseSyntax? GetConstraintClause(this Type type)
{
if (!type.IsGenericParameter) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,8 @@ protected override void Initialize(SourceProductionContext context, Compilation
{
if (x.IsGenericType)
{
if (x.GenericParameterCount() is not 1)
{
return null;
}

if (!x.IsConstructedGenericType)
{
x = x.GetGenericTypeDefinition();
}
if (x.GenericParameterCount() is not 1) return null;
if (!x.IsConstructedGenericType) x = x.GetGenericTypeDefinition();
}

var prop = x
Expand All @@ -57,10 +50,7 @@ p is

if (prop == null) return null;
var nullable = ((Feast.CodeAnalysis.CompileTime.PropertyInfo)prop).HasNullableAnnotation;
if (!x.IsGenericType)
{
return Deconstructs(x.QualifiedFullName(), attr.Size, nullable);
}
if (!x.IsGenericType) return Deconstructs(x.QualifiedFullName(), attr.Size, nullable);

var element = prop.PropertyType;
return Deconstructs(x.GlobalQualifiedFullName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
(x.TargetSymbol as IMethodSymbol)!.ContainingType, SymbolEqualityComparer.Default))
{
var @class = (group.Key as INamedTypeSymbol)!;
var partial = @class.PartialClassDeclaration();
var partial = @class.PartialTypeDeclaration();
foreach (var syntax in group)
{
var method = (syntax.TargetSymbol as IMethodSymbol)!;
Expand Down Expand Up @@ -95,7 +95,7 @@ StatementSyntax Method(string name,ITypeSymbol type, AutoReport.MemberKind kind,
ctx.AddSource($"{nameof(AutoReport)}__.{@class.GetFullyQualifiedName()
.Replace("global::", string.Empty)}.g.cs",
CompilationUnit()
.AddPartialClass(@class, x => partial)
.AddPartialType(@class, x => partial)
.NormalizeWhitespace()
.GetText(Encoding.UTF8));
return;
Expand Down
Loading

0 comments on commit 49617e8

Please sign in to comment.