New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce TypeResolver with member filter and name comparer #951
Conversation
c82eea1
to
00420a1
Compare
00420a1
to
12981f2
Compare
Given the fact that engines cannot be reused for parallel access I think the caching per engine could cause a downgrade in performance. Perhaps we should get rid of the options class and use dedicated class instances for the different tasks. E.g. a "TypeResolver" or so, that is passed to the engine. Then you can decide how you want to do the caching. |
I think that might get quite hard for end user to grasp how things affect performance based on instances provided. I don't know if there's a silver bullet here, unless we move the configuration to code (decorate members with attributes). |
I think very often members are only accessed once and I am afraid that the cache has very little impact if it is not shared. But lets say you define the options like this:
Then...
|
I've pushed changes to add |
@SebastianStehle thanks for your valuable input, I'd be happy to refine more if needed. |
Lgtm |
Looks great y'all! Is there a chance this could work with static members (exposed with TypeReference) as well? Or is that outside the scope of this PR / project? For example, I expose a static Log class which has a static "Debug" method (to print messages): public static class Log
{
[ScriptAllowed] // With the proposed TypeResolver.MemberFilter I can allow this method to be accessed (awesome!)
public static void Debug(string message)
=> UnityEngine.Debug.Log(message);
// ... etc engine.SetValue("Log", TypeReference.CreateTypeReference(engine, typeof(Log))); In JavaScript I wish to call (name comparison is already handled by the currently proposed TypeResolver.MemberNameComparer): Log.debug("Hello World") (instead of Log.Debug) |
@luttje I've changed |
6c8feb4
to
faa9836
Compare
Awesome work @lahma, kudos! Great to see this picked up swiftly and implemented cleanly. I don't want to seem demanding, but if you have some spare time would you mind publishing this to NuGet? I tried using the MyGet feed, but that seems to be outdated. Or am I doing something wrong? |
@luttje working on it. Unfortunately new GitHub Actions pipeline doesn't push to MyGet so NuGet is needed, Hopefully a new release won't take that long. |
@luttje new releases should be now available on NuGet |
Amazing work @lahma! I think I'm going to cry though, after all your effort I can't use Jint as is. I'm using Unity (currently on C# 8.0) and your use of the |
I had no idea that there's some backwards usage restriction for such properties. My guess would have been compiler would ignore non-init usage. Usually compiler features do not reflect to actual IL. The init-only usage was to ensure nobody goes doing crazy stuff w.r.t. threading (setting properties outside of engine), but it's not mandatory. I'm still confused how this can cause trouble based on library version. |
I think the logic is good, but for some reason Unity won't accept me setting the members. Copying from this test in Unity gives this error: |
A smaller test-case without Unity and just a C# 8.0 Console Application yields a more explicit error (telling me to go use 9.0) when using the latest Jint pre-release. Don't look at this ugly workaround for C# < 9.0 that works 😅 var typeResolver = new TypeResolver();
var type = typeResolver.GetType();
var memberNameProperty = type.GetProperty("MemberNameComparer");
memberNameProperty.SetValue(typeResolver, StringComparer.OrdinalIgnoreCase);
Predicate<MemberInfo> filter = member =>
{
return !Attribute.IsDefined(member, typeof(ObsoleteAttribute));
};
var memberFilterProperty = type.GetProperty("MemberFilter");
memberFilterProperty.SetValue(typeResolver, filter);
engine = new Engine(options =>
{
options.SetTypeResolver(typeResolver);
}); I can live with this until Unity upgrades to C# 9.0. |
The issue with Unity/C# 8 has been now fixed in main. I think you've found a workaround for now, also make sure to share the |
Oh awesome. Thank you very much for your work! ✌️ I'll keep in mind to share the TypeResolver instance if I have more Engines. |
ok. it is allow to enable and disable whole property. And what about disabling only get or set method of property? |
Setting a filter allows to reuse all resolution logic and wrapping and on top of that just filter with
MemberInfo
. Now also caching resolution per engine as options are per engine.Also adding custom property name comparer.
fixes #275
fixes #342