mirror of
				https://github.com/esiur/esiur-dotnet.git
				synced 2025-11-04 09:21:35 +00:00 
			
		
		
		
	Type Annotation
This commit is contained in:
		@@ -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>
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {{");
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
 | 
			
		||||
namespace Test
 | 
			
		||||
{
 | 
			
		||||
    [Resource]
 | 
			
		||||
    [Annotation("A", "B", "C", "D")]
 | 
			
		||||
    public partial class MyResource
 | 
			
		||||
    {
 | 
			
		||||
        [Public] string description;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user