public PhpAlias GetAlias(ref PhpValue value, Context ctx, Type classContext) { PhpValue tmp; if (value.AsObject() is ArrayAccess arrayaccess) { // special case for ArrayAccess avoids conversion to IntStringKey tmp = arrayaccess.offsetGet(Key); switch (Next.Operation) { case RuntimeChainOperation.ArrayItem: tmp = PhpValue.EnsureAlias(ref tmp); break; case RuntimeChainOperation.Property: tmp = PhpValue.FromClass(PhpValue.EnsureObject(ref tmp)); break; case RuntimeChainOperation.End: return(PhpValue.EnsureAlias(ref tmp)); default: throw new InvalidOperationException(); } } else { var arr = PhpValue.EnsureArray(ref value); switch (Next.Operation) { case RuntimeChainOperation.ArrayItem: tmp = PhpValue.Create(arr.EnsureItemArray(Key)); break; case RuntimeChainOperation.Property: tmp = PhpValue.FromClass(arr.EnsureItemObject(Key)); break; case RuntimeChainOperation.End: return(arr.EnsureItemAlias(Key)); default: throw new InvalidOperationException(); } } // return(Next.GetAlias(ref tmp, ctx, classContext)); }
ref PhpValue Ensure(ref PhpValue value) { Debug.Assert(Next.Operation != RuntimeChainOperation.End); switch (Next.Operation) { case RuntimeChainOperation.Value: break; case RuntimeChainOperation.Property: value = PhpValue.FromClass(PhpValue.EnsureObject(ref value)); break; case RuntimeChainOperation.ArrayItem: value = PhpValue.Create(PhpValue.EnsureArray(ref value)); break; default: throw new InvalidOperationException(); } // return(ref value); }
public virtual object EnsureObject(Context ctx, object instance) { var value = GetValue(ctx, instance); return(PhpValue.EnsureObject(ref value)); }
public PhpAlias GetAlias(ref PhpValue value, Context ctx, Type classContext) { var receiver = PhpValue.EnsureObject(ref value); var t = receiver.GetPhpTypeInfo(); PhpValue tmp; if (BinderHelpers.TryResolveDeclaredProperty(t, classContext, false, Name, out var prop)) { switch (Next.Operation) { case RuntimeChainOperation.Property: tmp = PhpValue.FromClass(prop.EnsureObject(ctx, receiver)); break; case RuntimeChainOperation.ArrayItem: tmp = PhpValue.Create(prop.EnsureArray(ctx, receiver)); break; case RuntimeChainOperation.End: return(prop.EnsureAlias(ctx, receiver)); default: throw new InvalidOperationException(); } } else { // Template: runtimeflds.Contains(key) ? runtimeflds.EnsureObject(key) : ( __get(key) ?? runtimeflds.EnsureObject(key)) var runtimeFields = t.GetRuntimeFields(receiver); if (runtimeFields == null || !runtimeFields.Contains(Name)) { // var __get = t.RuntimeMethods[TypeMethods.MagicMethods.__get]; if (__get != null) { // NOTE: magic methods must have public visibility, therefore the visibility check is unnecessary // int subkey1 = access.Write() ? 1 : access.Unset() ? 2 : access.Isset() ? 3 : 4; int subkey = Name.GetHashCode() ^ (1 << 4 /*subkey1*/); using (var token = new Context.RecursionCheckToken(ctx, receiver, subkey)) { if (!token.IsInRecursion) { tmp = __get.Invoke(ctx, receiver, Name); return(Next.GetAlias(ref tmp, ctx, classContext)); } } } } if (runtimeFields == null) { runtimeFields = t.EnsureRuntimeFields(receiver); } // switch (Next.Operation) { case RuntimeChainOperation.Property: tmp = PhpValue.FromClass(runtimeFields.EnsureItemObject(Name)); break; case RuntimeChainOperation.ArrayItem: tmp = PhpValue.Create(runtimeFields.EnsureItemArray(Name)); break; case RuntimeChainOperation.End: return(runtimeFields.EnsureItemAlias(Name)); default: throw new InvalidOperationException(); } } // chain: return(Next.GetAlias(ref tmp, ctx, classContext)); }