2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-05-06 11:32:59 +00:00

Type Annotation

This commit is contained in:
Esiur Project 2022-06-11 18:50:08 +03:00
parent 70ac2db694
commit 80922a13ee
6 changed files with 102 additions and 24 deletions

View File

@ -6,7 +6,7 @@
<Copyright>Ahmed Kh. Zamil</Copyright>
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.2.2</Version>
<Version>2.2.3</Version>
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
<Authors>Ahmed Kh. Zamil</Authors>
<AssemblyVersion></AssemblyVersion>
@ -62,21 +62,21 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.0.1" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.2.0" />
<PackageReference Include="System.Collections" Version="4.3.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Interactive.Async" Version="5.1.0" />
<PackageReference Include="System.Interactive.Async" Version="6.0.1" />
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
<PackageReference Include="System.Net.Security" Version="4.3.2" />
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
<PackageReference Include="System.Text.Json" Version="6.0.1" GeneratePathProperty="true" />
<PackageReference Include="System.Text.Json" Version="6.0.4" GeneratePathProperty="true" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
</ItemGroup>

View File

@ -15,6 +15,49 @@ public static class TemplateGenerator
{
internal static Regex urlRegex = new Regex(@"^(?:([\S]*)://([^/]*)/?)");
//public static string ToLiteral(string valueTextForCompiler)
//{
// return SymbolDisplay.FormatLiteral(valueTextForCompiler, false);
//}
static string ToLiteral(string input)
{
var literal = new StringBuilder();
literal.Append("\"");
foreach (var c in input)
{
switch (c)
{
case '\"': literal.Append("\\\""); break;
case '\\': literal.Append(@"\\"); break;
case '\0': literal.Append(@"\0"); break;
case '\a': literal.Append(@"\a"); break;
case '\b': literal.Append(@"\b"); break;
case '\f': literal.Append(@"\f"); break;
case '\n': literal.Append(@"\n"); break;
case '\r': literal.Append(@"\r"); break;
case '\t': literal.Append(@"\t"); break;
case '\v': literal.Append(@"\v"); break;
default:
// ASCII printable character
if (c >= 0x20 && c <= 0x7e)
{
literal.Append(c);
// As UTF16 escaped character
}
else
{
literal.Append(@"\u");
literal.Append(((int)c).ToString("x4"));
}
break;
}
}
literal.Append("\"");
return literal.ToString();
}
internal static string GenerateRecord(TypeTemplate template, TypeTemplate[] templates)
{
var cls = template.ClassName.Split('.');
@ -22,10 +65,15 @@ public static class TemplateGenerator
var nameSpace = string.Join(".", cls.Take(cls.Length - 1));
var className = cls.Last();
var rt = new StringBuilder();
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
rt.AppendLine($"namespace { nameSpace} {{");
if (template.Annotation != null)
rt.AppendLine($"[Annotation({ToLiteral(template.Annotation)})]");
rt.AppendLine($"[Public] public class {className} : IRecord {{");
@ -52,6 +100,10 @@ public static class TemplateGenerator
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
rt.AppendLine($"namespace { nameSpace} {{");
if (template.Annotation != null)
rt.AppendLine($"[Annotation({ToLiteral(template.Annotation)})]");
rt.AppendLine($"[Public] public enum {className} {{");
rt.AppendLine(String.Join(",\r\n", template.Constants.Select(x => $"{x.Name}={x.Value}")));
@ -213,6 +265,9 @@ public static class TemplateGenerator
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
rt.AppendLine($"namespace { nameSpace} {{");
if (template.Annotation != null)
rt.AppendLine($"[Annotation({ToLiteral(template.Annotation)})]");
// extends
if (template.ParentId == null)
rt.AppendLine($"public class {className} : DistributedResource {{");

View File

@ -4,7 +4,7 @@ using System.Text;
namespace Esiur.Resource;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event)]
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event)]
public class AnnotationAttribute : Attribute
{
@ -13,4 +13,8 @@ public class AnnotationAttribute : Attribute
{
this.Annotation = annotation;
}
public AnnotationAttribute(params string[] annotations)
{
this.Annotation = String.Join("\n", annotations);
}
}

View File

@ -25,6 +25,8 @@ public class TypeTemplate
protected Guid classId;
protected Guid? parentId;
public string Annotation { get; set; }
string className;
List<MemberTemplate> members = new List<MemberTemplate>();
List<FunctionTemplate> functions = new List<FunctionTemplate>();
@ -157,7 +159,6 @@ public class TypeTemplate
}
public static Guid GetTypeGuid(Type type) => GetTypeGuid(GetTypeClassName(type));
public static Guid GetTypeGuid(string typeName)
@ -403,6 +404,7 @@ public class TypeTemplate
Warehouse.PutTemplate(this);
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); // | BindingFlags.DeclaredOnly);
@ -772,31 +774,37 @@ public class TypeTemplate
// find the first parent type that implements IResource
var hasParent = HasParent(type);
var classAnnotation = type.GetCustomAttribute<AnnotationAttribute>(false);
var hasAnnotation = classAnnotation != null && classAnnotation.Annotation != null;
if (HasParent(type))
var classNameBytes = DC.ToBytes(className);
b.AddUInt8((byte)((hasParent ? 0x80 : 0) | (hasAnnotation ? 0x40 : 0x0) | (byte)templateType))
.AddGuid(classId)
.AddUInt8((byte)classNameBytes.Length)
.AddUInt8Array(classNameBytes);
if (hasParent)
{
// find the first parent type that implements IResource
var ParentDefinedType = ResourceProxy.GetBaseType(type.BaseType);
var parentId = GetTypeGuid(ParentDefinedType);
b.AddGuid(parentId);
}
b.AddUInt8((byte)(0x80 | (byte)templateType))
.AddGuid(classId)
.AddUInt8((byte)className.Length)
.AddString(className)
.AddGuid(parentId)
.AddInt32(version)
.AddUInt16((ushort)members.Count);
}
else
if (hasAnnotation)
{
b.AddUInt8((byte)templateType)
.AddGuid(classId)
.AddUInt8((byte)className.Length)
.AddString(className)
.AddInt32(version)
.AddUInt16((ushort)members.Count);
var classAnnotationBytes = DC.ToBytes(classAnnotation.Annotation);
b.AddUInt16((ushort)classAnnotationBytes.Length)
.AddUInt8Array(classAnnotationBytes);
Annotation = classAnnotation.Annotation;
}
b.AddInt32(version)
.AddUInt16((ushort)members.Count);
foreach (var ft in functions)
b.AddUInt8Array(ft.Compose());
foreach (var pt in properties)
@ -848,6 +856,8 @@ public class TypeTemplate
od.content = data.Clip(offset, contentLength);
var hasParent = (data[offset] & 0x80) > 0;
var hasAnnotation = (data[offset] & 0x40) > 0;
od.templateType = (TemplateType)(data[offset++] & 0xF);
od.classId = data.GetGuid(offset);
@ -862,6 +872,14 @@ public class TypeTemplate
offset += 16;
}
if (hasAnnotation)
{
var len = data.GetUInt16(offset, Endian.Little);
offset += 2;
od.Annotation = data.GetString(offset, len);
offset += len;
}
od.version = data.GetInt32(offset, Endian.Little);
offset += 4;

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
namespace Test
{
[Resource]
[Annotation("A", "B", "C", "D")]
public partial class MyResource
{
[Public] string description;