示例#1
0
 public ExprNodeVarargOnlyArrayEvalNoCoerce(
     ExprNodeVarargOnlyArrayForge forge,
     ExprEvaluator[] evals)
 {
     this.forge = forge;
     this.evals = evals;
 }
示例#2
0
        internal static Pair<ExprForge[], ExprEvaluator[]> MakeVarargArrayEval(
            MethodInfo method,
            ExprForge[] childForges)
        {
            var methodParameterTypes = method.GetParameterTypes();
            ExprEvaluator[] evals = new ExprEvaluator[methodParameterTypes.Length];
            ExprForge[] forges = new ExprForge[methodParameterTypes.Length];
            Type varargClass = methodParameterTypes[methodParameterTypes.Length - 1].GetElementType();
            Type varargClassBoxed = varargClass.GetBoxedType();
            if (methodParameterTypes.Length > 1) {
                Array.Copy(childForges, 0, forges, 0, forges.Length - 1);
            }

            int varargArrayLength = childForges.Length - methodParameterTypes.Length + 1;

            // handle passing array along
            if (varargArrayLength == 1) {
                ExprForge lastForge = childForges[methodParameterTypes.Length - 1];
                Type lastReturns = lastForge.EvaluationType;
                if (lastReturns != null && lastReturns.IsArray) {
                    forges[methodParameterTypes.Length - 1] = lastForge;
                    return new Pair<ExprForge[], ExprEvaluator[]>(forges, evals);
                }
            }

            // handle parameter conversion to vararg parameter
            ExprForge[] varargForges = new ExprForge[varargArrayLength];
            Coercer[] coercers = new Coercer[varargForges.Length];
            bool needCoercion = false;
            for (int i = 0; i < varargArrayLength; i++) {
                int childIndex = i + methodParameterTypes.Length - 1;
                Type resultType = childForges[childIndex].EvaluationType;
                varargForges[i] = childForges[childIndex];

                if (resultType == null && varargClass.CanBeNull()) {
                    continue;
                }

                if (TypeHelper.IsSubclassOrImplementsInterface(resultType, varargClass)) {
                    // no need to coerce
                    continue;
                }

                if (resultType.GetBoxedType() != varargClassBoxed) {
                    needCoercion = true;
                    coercers[i] = SimpleNumberCoercerFactory.GetCoercer(resultType, varargClassBoxed);
                }
            }

            ExprForge varargForge = new ExprNodeVarargOnlyArrayForge(
                varargForges,
                varargClass,
                needCoercion ? coercers : null);
            forges[methodParameterTypes.Length - 1] = varargForge;
            evals[methodParameterTypes.Length - 1] = varargForge.ExprEvaluator;
            return new Pair<ExprForge[], ExprEvaluator[]>(forges, evals);
        }