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(); }
void ProcessTarget(DynamicMetaObject target) { Debug.Assert(target != null); if (BinderHelpers.TryTargetAsObject(target, out target)) { this.AddRestriction(target.Restrictions); this.TargetInstance = target.Expression; this.CurrentTargetInstance = target.Value; if (this.TargetType == null && target.Value != null) { this.TargetType = target.Value.GetPhpTypeInfo(); } } }
public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { var restrictions = BindingRestrictions.Empty; Expression target_expr; PhpTypeInfo phptype; // string fldName; Expression value; ResolveArgs(args, ref restrictions, out fldName, out value); var ctx = args[args.Length - 1]; // if (target.LimitType == typeof(PhpTypeInfo)) // static field { target_expr = null; phptype = (PhpTypeInfo)target.Value; } else { var isobject = BinderHelpers.TryTargetAsObject(target, out DynamicMetaObject instance); if (isobject == false) { throw new NotSupportedException(); } restrictions = restrictions.Merge(instance.Restrictions); target_expr = Expression.Convert(instance.Expression, instance.RuntimeType); phptype = instance.RuntimeType.GetPhpTypeInfo(); } // var setter = BinderHelpers.BindField(phptype, _classContext, target_expr, fldName, ctx.Expression, _access, value); if (setter != null) { // return(new DynamicMetaObject(setter, restrictions)); } // field not found throw new NotImplementedException(); }
protected override MethodBase[] ResolveMethods(DynamicMetaObject ctx, PhpTypeInfo tinfo, DynamicMetaObject nameExpr, ref DynamicMetaObject target, IList <DynamicMetaObject> args, ref BindingRestrictions restrictions) { // resolve target expression: var isobject = BinderHelpers.TryTargetAsObject(target, out DynamicMetaObject instance); restrictions = restrictions.Merge(instance.Restrictions); target = new DynamicMetaObject(Expression.Convert(instance.Expression, instance.RuntimeType), target.Restrictions, instance.Value); if (isobject == false) { return(null); // no methods } string name = _name ?? (string)nameExpr.Value; // candidates: var candidates = target.RuntimeType.GetPhpTypeInfo().SelectRuntimeMethods(name).SelectVisible(_classCtx).ToList(); return(candidates.ToArray()); }
protected override Expression BindMissingMethod(DynamicMetaObject ctx, PhpTypeInfo tinfo, DynamicMetaObject nameMeta, DynamicMetaObject target, IList <DynamicMetaObject> args, ref BindingRestrictions restrictions) { var name_expr = (_name != null) ? Expression.Constant(_name) : nameMeta?.Expression; // resolve target expression: var isobject = BinderHelpers.TryTargetAsObject(target, out DynamicMetaObject instance); restrictions = restrictions.Merge(instance.Restrictions); if (isobject == false) { /* Template: * PhpException.MethodOnNonObject(name_expr); // aka PhpException.Throw(Error, method_called_on_non_object, name_expr) * return NULL; */ var throwcall = Expression.Call(typeof(PhpException), "MethodOnNonObject", Array.Empty <Type>(), ConvertExpression.Bind(name_expr, typeof(string), ctx.Expression)); return(Expression.Block(throwcall, ConvertExpression.BindDefault(this.ReturnType))); } Debug.Assert(ReflectionUtils.IsClassType(instance.RuntimeType.GetTypeInfo())); tinfo = instance.RuntimeType.GetPhpTypeInfo(); var call = BinderHelpers.FindMagicMethod(tinfo, TypeMethods.MagicMethods.__call); if (call != null) { // target.__call(name, array) var call_args = new Expression[] { name_expr, BinderHelpers.NewPhpArray(ctx.Expression, args.Select(a => a.Expression)), }; return(OverloadBinder.BindOverloadCall(_returnType, target.Expression, call.Methods, ctx.Expression, call_args)); } return(base.BindMissingMethod(ctx, tinfo, nameMeta, target, args, ref restrictions)); }