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

Source Generation

This commit is contained in:
Ahmed Zamil 2021-05-17 05:34:09 +03:00
parent 5bf258673d
commit c8683e17e9
16 changed files with 148 additions and 57 deletions

View File

@ -34,6 +34,7 @@ using System.Runtime.CompilerServices;
namespace Esiur.Stores.EntityCore namespace Esiur.Stores.EntityCore
{ {
public class EntityResource : IResource public class EntityResource : IResource
{ {
//[NotMapped] //[NotMapped]

View File

@ -9,9 +9,17 @@
<Product>Esiur Entity Framework Extension</Product> <Product>Esiur Entity Framework Extension</Product>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>Esiur.Stores.EntityCore</PackageId> <PackageId>Esiur.Stores.EntityCore</PackageId>
<Version>1.0.2</Version> <Version>1.1.0</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Compile Remove="EntityResource.cs" />
</ItemGroup>
<ItemGroup>
<None Include="EntityResource.cs" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.6" />
<PackageReference Include="System.Collections" Version="4.3.0" /> <PackageReference Include="System.Collections" Version="4.3.0" />

View File

@ -76,7 +76,7 @@ namespace Esiur.Stores.EntityCore
return cache; return cache;
// check if the object exists // check if the object exists
var obj = Warehouse.New(entityType.ClrType).Wait() as EntityResource;//, "", options.Store, null, manager); var obj = Warehouse.New(entityType.ClrType).Wait() as IResource;//, "", options.Store, null, manager);
//obj._PrimaryId = id; //obj._PrimaryId = id;
options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id); options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id);
Warehouse.Put(id.ToString(), obj, options.Store, null, null, 0, manager).Wait(); Warehouse.Put(id.ToString(), obj, options.Store, null, null, 0, manager).Wait();

View File

@ -11,13 +11,13 @@
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl> <PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
<RepositoryUrl>https://github.com/esiur/esiur-dotnet/</RepositoryUrl> <RepositoryUrl>https://github.com/esiur/esiur-dotnet/</RepositoryUrl>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild> <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Version>1.4.1</Version> <Version>1.5.0</Version>
<PackageId>Esiur.Stores.MongoDB</PackageId> <PackageId>Esiur.Stores.MongoDB</PackageId>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MongoDB.Bson" Version="2.9.1" /> <PackageReference Include="MongoDB.Bson" Version="2.12.3" />
<PackageReference Include="MongoDB.Driver" Version="2.9.1" /> <PackageReference Include="MongoDB.Driver" Version="2.12.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -159,7 +159,7 @@ namespace Esiur.Stores.MongoDB
resources.Add(id, new WeakReference(resource)); resources.Add(id, new WeakReference(resource));
//@TODO this causes store.put to be invoked, need fix //@TODO this causes store.put to be invoked, need fix
await Warehouse.Put(resource, document["name"].AsString, this); await Warehouse.Put(document["name"].AsString, resource, this);
var parents = document["parents"].AsBsonArray; var parents = document["parents"].AsBsonArray;

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Core
{
public enum ExceptionLevel
{
Code = 0x1,
Message = 0x2,
Source = 0x4,
Trace = 0x8
}
}

View File

@ -7,12 +7,12 @@
<PackageLicenseUrl>https://github.com/Esiur/Esiur-dotnet/blob/master/LICENSE</PackageLicenseUrl> <PackageLicenseUrl>https://github.com/Esiur/Esiur-dotnet/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl> <PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.6.1</Version> <Version>1.7.1</Version>
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl> <RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
<Authors>Ahmed Kh. Zamil</Authors> <Authors>Ahmed Kh. Zamil</Authors>
<AssemblyVersion>1.6.0</AssemblyVersion> <AssemblyVersion>1.7.1</AssemblyVersion>
<Company>Esiur Foundation</Company> <Company>Esiur Foundation</Company>
<FileVersion>1.6.0</FileVersion> <FileVersion>1.7.1</FileVersion>
<AssemblyName>Esiur</AssemblyName> <AssemblyName>Esiur</AssemblyName>
<RootNamespace>Esiur</RootNamespace> <RootNamespace>Esiur</RootNamespace>
<PackageId>Esiur</PackageId> <PackageId>Esiur</PackageId>
@ -57,6 +57,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.9.0" /> <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.9.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" /> <PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" /> <PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Interactive.Async" Version="5.0.0" /> <PackageReference Include="System.Interactive.Async" Version="5.0.0" />
@ -72,4 +73,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
</Project> </Project>

View File

@ -1164,6 +1164,22 @@ namespace Esiur.Net.IIP
} }
[Attribute]
public ExceptionLevel ExceptionLevel { get; set; }
= ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace;
private Tuple<ushort, string> SummerizeException(Exception ex)
{
ex = ex.InnerException != null ? ex.InnerException : ex;
var code = (ExceptionLevel & ExceptionLevel.Code) == 0 ? 0 : ex is AsyncException ae ? ae.Code : 0;
var msg = (ExceptionLevel & ExceptionLevel.Message) == 0 ? "" : ex.Message;
var source = (ExceptionLevel & ExceptionLevel.Source) == 0 ? "" : ex.Source;
var trace = (ExceptionLevel & ExceptionLevel.Trace) == 0 ? "" : ex.StackTrace;
return new Tuple<ushort, string>((ushort)code, $"{source}: {msg}\n{trace}");
}
void IIPRequestInvokeFunctionArrayArguments(uint callback, uint resourceId, byte index, byte[] content) void IIPRequestInvokeFunctionArrayArguments(uint callback, uint resourceId, byte index, byte[] content)
{ {
//Console.WriteLine("IIPRequestInvokeFunction " + callback + " " + resourceId + " " + index); //Console.WriteLine("IIPRequestInvokeFunction " + callback + " " + resourceId + " " + index);
@ -1247,8 +1263,8 @@ namespace Esiur.Net.IIP
} }
catch (Exception ex) catch (Exception ex)
{ {
SendError(ErrorType.Exception, callback, 0, var (code, msg) = SummerizeException(ex);
ex.InnerException != null ? ex.InnerException.ToString() : ex.ToString()); SendError(ErrorType.Exception, callback, code, msg);
return; return;
} }
@ -1266,7 +1282,8 @@ namespace Esiur.Net.IIP
} }
catch (Exception ex) catch (Exception ex)
{ {
SendError(ErrorType.Exception, callback, 0, ex.ToString()); var (code, msg) = SummerizeException(ex);
SendError(ErrorType.Exception, callback, code, msg);
} }
} }
@ -1297,7 +1314,8 @@ namespace Esiur.Net.IIP
.Done(); .Done();
}).Error(ex => }).Error(ex =>
{ {
SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message); var (code, msg) = SummerizeException(ex);
SendError(ErrorType.Exception, callback, code, msg);
}).Progress((pt, pv, pm) => }).Progress((pt, pv, pm) =>
{ {
SendProgress(callback, pv, pm); SendProgress(callback, pv, pm);
@ -1412,7 +1430,8 @@ namespace Esiur.Net.IIP
} }
catch (Exception ex) catch (Exception ex)
{ {
SendError(ErrorType.Exception, callback, 0, ex.ToString()); var (code, msg) = SummerizeException(ex);
SendError(ErrorType.Exception, callback, code, msg);
return; return;
} }
@ -1431,7 +1450,8 @@ namespace Esiur.Net.IIP
} }
catch (Exception ex) catch (Exception ex)
{ {
SendError(ErrorType.Exception, callback, 0, ex.ToString()); var (code, msg) = SummerizeException(ex);
SendError(ErrorType.Exception, callback, code, msg);
} }
} }
else if (rt is Task) else if (rt is Task)
@ -1459,7 +1479,8 @@ namespace Esiur.Net.IIP
}).Error(ex => }).Error(ex =>
{ {
SendError(ErrorType.Exception, callback, (ushort)ex.Code, ex.Message); var (code, msg) = SummerizeException(ex);
SendError(ErrorType.Exception, callback, code, msg);
}).Progress((pt, pv, pm) => }).Progress((pt, pv, pm) =>
{ {
SendProgress(callback, pv, pm); SendProgress(callback, pv, pm);

View File

@ -68,6 +68,13 @@ namespace Esiur.Net.IIP
} }
[Attribute]
public ExceptionLevel ExceptionLevel { get; set; }
= ExceptionLevel.Code
| ExceptionLevel.Source
| ExceptionLevel.Message
| ExceptionLevel.Trace;
public Instance Instance public Instance Instance
{ {
@ -147,6 +154,7 @@ namespace Esiur.Net.IIP
public override void Add(DistributedConnection connection) public override void Add(DistributedConnection connection)
{ {
connection.Server = this; connection.Server = this;
connection.ExceptionLevel = ExceptionLevel;
base.Add(connection); base.Add(connection);
} }

View File

@ -24,12 +24,14 @@ namespace Esiur.Proxy
if (!(context.SyntaxContextReceiver is ResourceGeneratorReceiver receiver)) if (!(context.SyntaxContextReceiver is ResourceGeneratorReceiver receiver))
return; return;
//#if DEBUG try
// if (!Debugger.IsAttached) {
// { //#if DEBUG
// Debugger.Launch(); // if (!Debugger.IsAttached)
// } // {
//#endif // Debugger.Launch();
// }
//#endif
//var toImplement = receiver.Classes.Where(x => x.Fields.Length > 0); //var toImplement = receiver.Classes.Where(x => x.Fields.Length > 0);
@ -51,21 +53,29 @@ public virtual void Destroy() {{ OnDestroy?.Invoke(this); }}
"; ";
if (!ci.ImplementTrigger) if (!ci.ImplementTrigger)
code += "public AsyncReply<bool> Trigger(ResourceTrigger trigger) => new AsyncReply<bool>(true);"; code += "public AsyncReply<bool> Trigger(ResourceTrigger trigger) => new AsyncReply<bool>(true);\r\n";
} }
foreach (var f in ci.Fields) foreach (var f in ci.Fields)
{ {
var fn = f.Name; var fn = f.Name;
var pn = fn.Substring(0, 1).ToUpper() + fn.Substring(1); var pn = fn.Substring(0, 1).ToUpper() + fn.Substring(1);
code += $@"[Public] public {f.Type} {pn} {{ get => {fn}; set {{ {fn} = value; Instance.Modified(); }} }}";
// copy attributes
var attrs = string.Join(" ", f.GetAttributes().Select(x => $"[{x.ToString()}]"));
code += $"{attrs} public {f.Type} {pn} {{ get => {fn}; set {{ {fn} = value; Instance?.Modified(); }} }}\r\n";
} }
code += "}}"; code += "}}\r\n";
//System.IO.File.WriteAllText("C:\\www\\class.cs", code); //System.IO.File.WriteAllText("c:\\gen\\" + ci.Name + "_esiur.cs", code);
context.AddSource(ci.Name + "_esiur.cs", code); context.AddSource(ci.Name + "_esiur.cs", code);
} }
} }
catch //(Exception ex)
{
//System.IO.File.AppendAllText("c:\\gen\\error.log", ex.ToString() + "\r\n");
}
}
} }
} }

View File

@ -6,7 +6,7 @@ using System.Text;
namespace Esiur.Proxy namespace Esiur.Proxy
{ {
public struct GenerationInfo public struct ResourceGeneratorClassInfo
{ {
public string Name { get; set; } public string Name { get; set; }
public bool ImplementInterface { get; set; } public bool ImplementInterface { get; set; }
@ -16,5 +16,6 @@ namespace Esiur.Proxy
public ITypeSymbol ClassSymbol { get; set; } public ITypeSymbol ClassSymbol { get; set; }
public ClassDeclarationSyntax ClassDeclaration { get; set; } public ClassDeclarationSyntax ClassDeclaration { get; set; }
} }
} }

View File

@ -0,0 +1,13 @@
using Microsoft.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Proxy
{
public struct ResourceGeneratorFieldInfo
{
public IFieldSymbol FieldSymbol { get; set; }
public string[] Attributes { get; set; }
}
}

View File

@ -11,7 +11,7 @@ namespace Esiur.Proxy
public class ResourceGeneratorReceiver : ISyntaxContextReceiver public class ResourceGeneratorReceiver : ISyntaxContextReceiver
{ {
public List<GenerationInfo> Classes { get; } = new(); public List<ResourceGeneratorClassInfo> Classes { get; } = new();
public void OnVisitSyntaxNode(GeneratorSyntaxContext context) public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
{ {
@ -23,10 +23,7 @@ namespace Esiur.Proxy
if (cls.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.ResourceAttribute")) if (cls.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.ResourceAttribute"))
{ {
//if (!Debugger.IsAttached)
//{
// Debugger.Launch();
//}
var hasTrigger = cds.Members var hasTrigger = cds.Members
.Where(x => x is MethodDeclarationSyntax) .Where(x => x is MethodDeclarationSyntax)
@ -40,9 +37,16 @@ namespace Esiur.Proxy
.Where(x => x.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.PublicAttribute")) .Where(x => x.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.PublicAttribute"))
.ToArray(); .ToArray();
//if (!Debugger.IsAttached)
//{
// if (cls.Name == "User")
// Debugger.Launch();
//}
// get fields // get fields
Classes.Add(new GenerationInfo() Classes.Add(new ResourceGeneratorClassInfo()
{ {
Name = cls.Name, Name = cls.Name,
ClassDeclaration = cds, ClassDeclaration = cds,

View File

@ -5,7 +5,7 @@ using System.Text;
namespace Esiur.Resource namespace Esiur.Resource
{ {
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Event)] [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event)]
public class AnnotationAttribute : Attribute public class AnnotationAttribute : Attribute
{ {

View File

@ -30,6 +30,7 @@ using Esiur.Data;
using Esiur.Core; using Esiur.Core;
using System.ComponentModel; using System.ComponentModel;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.ComponentModel.DataAnnotations.Schema;
namespace Esiur.Resource namespace Esiur.Resource
{ {
@ -41,6 +42,8 @@ namespace Esiur.Resource
{ {
AsyncReply<bool> Trigger(ResourceTrigger trigger); AsyncReply<bool> Trigger(ResourceTrigger trigger);
[NotMapped]
Instance Instance Instance Instance
{ {
get; get;

View File

@ -14,9 +14,11 @@ using Esiur.Security.Authority;
using Esiur.Proxy; using Esiur.Proxy;
using Esiur.Core; using Esiur.Core;
using System.Text.Json; using System.Text.Json;
using System.ComponentModel.DataAnnotations.Schema;
namespace Esiur.Resource namespace Esiur.Resource
{ {
[NotMapped]
public class Instance public class Instance
{ {
string name; string name;