@ -15,17 +15,13 @@ namespace Squidex.Domain.Apps.Core.Scripting;
public sealed class NullPropagation : IReferenceResolver
{
/// <summary>
/// The situations this resolver actually answers, declared so the engine keeps the fast paths for
/// everything else.
/// The cases this resolver actually handles.
/// </summary>
/// <remarks>
/// Deliberately omitted are <see cref="ReferenceResolverInterests.ObjectPropertyBase"/> and
/// <see cref="ReferenceResolverInterests.PrimitivePropertyBase"/>, the pair that disables the
/// non-computed member-read inline caches, the dense-array indexed-read lane and the member-call callee
/// lane engine-wide. <see cref="TryPropertyReference"/> declines every base that is not null or
/// undefined, so those are situations where the engine consulting this resolver could never change the
/// result. Interests are a subscription filter and not a promise: a situation not subscribed to behaves
/// exactly as if no resolver were registered.
/// Without this list Jint has to assume that we want to see every property read and turns off its read
/// caches for the whole engine. But <see cref="TryPropertyReference"/> only ever does something when the
/// value is null or undefined, so the other cases can be left to Jint. Behavior does not change: for a
/// case that is not listed here Jint behaves as if no resolver was registered at all.
/// </remarks>
public const ReferenceResolverInterests Interests =
ReferenceResolverInterests . NullishPropertyBase |
@ -35,16 +31,12 @@ public sealed class NullPropagation : IReferenceResolver
public static readonly NullPropagation Instance = new NullPropagation ( ) ;
/// <summary>
/// Answers a read of a name that resolves to no binding, so that an unknown name does not throw a
/// reference error.
/// Called when a name does not exist, so that reading an unknown variable does not throw.
/// </summary>
/// <remarks>
/// Passing the reference base straight through hands script the engine's internal sentinel for the
/// unresolvable state - a <see cref="JsString"/> reading <c>[[Unresolvable]]</c> - rather than
/// <c>undefined</c>, which is documented on <see cref="IReferenceResolver.TryUnresolvableReference"/> and
/// on <see cref="Reference.Base"/>. That is what scripts have always seen here, so it is kept and pinned
/// by a test; assigning <see cref="JsValue.Undefined"/> instead would be the tidier behaviour but a
/// breaking change for existing tenant scripts.
/// The returned base is not <c>undefined</c> here but an internal Jint marker string that reads
/// <c>[[Unresolvable]]</c>. That is what scripts have always seen, so it is kept as it is and covered by
/// a test. Returning <c>undefined</c> would be nicer, but would change behavior for existing scripts.
/// </remarks>
public bool TryUnresolvableReference ( Engine engine , Reference reference , out JsValue value )
{