public override void ProcessClosures(Context ctx) { if(LeftOperand is LambdaNode) LeftOperand.ProcessClosures(ctx); if (RightOperand is LambdaNode) RightOperand.ProcessClosures(ctx); var leftType = LeftOperand.GetExpressionType(ctx); var rightGetter = RightOperand as GetMemberNode; if (!IsLeft && leftType.IsCallableType() && rightGetter != null) { if (rightGetter.TypeHints.IsEmpty()) { var returnType = ctx.ResolveMethod(leftType, "Invoke").ReturnType; rightGetter.TypeHints = new List<TypeSignature> {TypeSignature.Parse(returnType.FullName)}; } } var rightType = RightOperand.GetExpressionType(ctx); if (rightGetter != null) rightGetter.TypeHints.Clear(); if (!IsLeft && leftType.IsCallableType() && rightType.IsCallableType()) { if (!ctx.CanCombineDelegates(leftType, rightType)) Error(Translations.CompilerMessages.DelegatesNotCombinable, leftType, rightType); var argTypes = ctx.WrapDelegate(leftType).ArgumentTypes; var argGetters = argTypes.Select((a, id) => Expr.GetArg(id)).Cast<NodeBase>().ToArray(); if (LeftOperand is GetMemberNode) (LeftOperand as GetMemberNode).TypeHints.Clear(); _Method = ctx.CurrentScope.CreateClosureMethod(ctx, argTypes, ctx.WrapDelegate(rightType).ReturnType); _Method.Body = Expr.Block( Expr.Invoke( RightOperand, Expr.Invoke( LeftOperand, argGetters ) ) ); var methodBackup = ctx.CurrentMethod; ctx.CurrentMethod = _Method; var scope = _Method.Scope; scope.InitializeScope(ctx); _Method.Body.ProcessClosures(ctx); _Method.PrepareSelf(); scope.FinalizeScope(ctx); ctx.CurrentMethod = methodBackup; } }
protected override Type resolveOperatorType(Context ctx, Type leftType, Type rightType) { if (leftType.IsAnyOf(typeof (int), typeof (long)) && rightType == typeof (int)) return leftType; if (!IsLeft && ctx.CanCombineDelegates(leftType, rightType)) return ctx.CombineDelegates(leftType, rightType); return null; }