public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { var restrictions = BindingRestrictions.Empty; PhpTypeInfo phptype; Expression target_expr; // var ctx = args[0]; var fldName = ResolveName(args, ref restrictions); // if (target.LimitType == typeof(PhpTypeInfo)) // static field { target_expr = null; phptype = (PhpTypeInfo)target.Value; // restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, phptype)); } else { var isobject = BinderHelpers.TryTargetAsObject(target, out DynamicMetaObject instance); restrictions = restrictions.Merge(instance.Restrictions); if (isobject == false) { var defaultexpr = ConvertExpression.BindDefault(_returnType); if (!_access.Quiet()) { // PhpException.VariableMisusedAsObject(target, _access.ReadRef) var throwcall = Expression.Call(typeof(PhpException), "VariableMisusedAsObject", Array.Empty <Type>(), ConvertExpression.BindToValue(target.Expression), Expression.Constant(_access.EnsureAlias())); defaultexpr = Expression.Block(throwcall, defaultexpr); } return(new DynamicMetaObject(defaultexpr, restrictions)); } phptype = instance.RuntimeType.GetPhpTypeInfo(); target_expr = target_expr = Expression.Convert(instance.Expression, instance.RuntimeType); } Debug.Assert(IsClassConst == (target_expr == null)); // var getter = IsClassConst ? BinderHelpers.BindClassConstant(phptype, _classContext, fldName, ctx.Expression) : BinderHelpers.BindField(phptype, _classContext, target_expr, fldName, ctx.Expression, _access, null); if (getter != null) { // return(new DynamicMetaObject(ConvertExpression.Bind(getter, _returnType, ctx.Expression), restrictions)); } // field not found throw new NotImplementedException(); }
public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { bool hasTargetInstance = (target.LimitType != typeof(TargetTypeParam)); var bound = new CallSiteContext(!hasTargetInstance) { ClassContext = _classContext, Name = _name } .ProcessArgs(target, args, hasTargetInstance); if (hasTargetInstance) { var isobject = bound.TargetType != null; if (isobject == false) { var defaultexpr = ConvertExpression.BindDefault(_returnType); if (!_access.Quiet()) { // PhpException.VariableMisusedAsObject(target, _access.ReadRef) var throwcall = BinderHelpers.VariableMisusedAsObject(target.Expression, _access.EnsureAlias()); defaultexpr = Expression.Block(throwcall, defaultexpr); } return(new DynamicMetaObject(defaultexpr, bound.Restrictions)); } // instance := (T)instance bound.TargetInstance = Expression.Convert(bound.TargetInstance, bound.TargetType.Type); } Debug.Assert(IsClassConst ? (bound.TargetInstance == null) : true); // var getter = IsClassConst ? BinderHelpers.BindClassConstant(bound.TargetType, bound.ClassContext, bound.Name, bound.Context) : BinderHelpers.BindField(bound.TargetType, bound.ClassContext, bound.TargetInstance, bound.Name, bound.Context, _access, null); if (getter != null) { // return(new DynamicMetaObject(ConvertExpression.Bind(getter, _returnType, bound.Context), bound.Restrictions)); } if (IsClassConst) { // error: constant not defined // ... } // unreachable: property not found throw new InvalidOperationException($"{bound.TargetType.Name}::{bound.Name} could not be resolved."); }
public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { bool hasTargetInstance = (target.LimitType != typeof(TargetTypeParam)); var bound = new CallSiteContext() { ClassContext = _classContext, Name = _name } .ProcessArgs(target, args, hasTargetInstance); if (hasTargetInstance) { var isobject = bound.TargetType != null; if (isobject == false) { var defaultexpr = ConvertExpression.BindDefault(_returnType); if (!_access.Quiet()) { // PhpException.VariableMisusedAsObject(target, _access.ReadRef) var throwcall = Expression.Call(typeof(PhpException), "VariableMisusedAsObject", Array.Empty <Type>(), ConvertExpression.BindToValue(target.Expression), Expression.Constant(_access.EnsureAlias())); defaultexpr = Expression.Block(throwcall, defaultexpr); } return(new DynamicMetaObject(defaultexpr, bound.Restrictions)); } // instance := (T)instance bound.TargetInstance = Expression.Convert(bound.TargetInstance, bound.TargetType.Type.AsType()); } Debug.Assert(IsClassConst ? (bound.TargetInstance == null) : true); // var getter = IsClassConst ? BinderHelpers.BindClassConstant(bound.TargetType, bound.ClassContext, bound.Name, bound.Context) : BinderHelpers.BindField(bound.TargetType, bound.ClassContext, bound.TargetInstance, bound.Name, bound.Context, _access, null); if (getter != null) { // return(new DynamicMetaObject(ConvertExpression.Bind(getter, _returnType, bound.Context), bound.Restrictions)); } // field not found throw new NotImplementedException(); }