CSE.Exps.MethodExp.Parse C# (CSharp) Method

Parse() public static method

Parses method calls
public static Parse ( CseObject environment, string methName, List args ) : CseObject
environment CseObject The environment containing the method
methName string Name of the method
args List CseObject array containing arguments to be sent to the method. Each CseObject is one argument
return CseObject
		public static CseObject Parse(CseObject environment, string methName, List<CseObject> args) {
			MethResSettings mrSettings = new MethResSettings() {
				Args = (args == null ? new CseObject[] { } : args.ToArray()),
				Env = environment.Value,
				Name = methName
			};
			List<MethResObject> appMeths = MethRes.GetApplicableMembers(mrSettings);

			if (appMeths.Count == 0) {
				mrSettings.IsExtInvocation = true;
				appMeths = MethRes.GetApplicableMembers(mrSettings);
			}

			MethodInfo mi = null;
			Type envType = TypeExp.GetTypeObj(environment.Value);

			try {
				switch (appMeths.Count) {
					// No methods exist with that name
					case 0:
						// TODO: doesn't exist OR no applicable methods can be called
						throw new CseLogicException(CseLogicExceptionType.METHOD_DOESNT_EXIST, methName);

					// Only 1 method exists with that name, so try to do what's necessary to coerce args (if they exist)
					// to match its signature.
					case 1:
						MethResObject mrObj = appMeths[0];

						if (args != null) {
							for (int i = 0; i < args.Count; i++) {
								try {
									args[i] = CastExp.Parse(environment, mrObj.MethInfo.GetParameters()[i].ParameterType.Name, args[i]);
								}
								catch (CseLogicException) {
									// fuck it, continue
								}
							}
						}
						//NarrowAllIntTypes(ref args);

						mi = mrObj.MethInfo;
						break;

					// Method is overloaded.
					// Idea is to simulate C#'s best match algorithm for finding the most appropriate method to call
					// and if still unsure, throw exception so user can use casting for further clarification.
					default:
						Type[] types = GetTypeArray(args);

						mi = envType.GetMethod(methName, findFlags | BindingFlags.ExactBinding, null, types, null);

						if (mi != null)
							break;

						if (CanCoerce(args)) {
							NarrowAllIntTypes(ref args);
							types = GetTypeArray(args);
						}

						MethodInfo tryMeth = envType.GetMethod(methName, findFlags, null, types, null);
						foreach (MethResObject m in appMeths) {
							if (m.MethInfo == tryMeth) {
								mi = tryMeth;
								break;
							}
						}

						if (mi != null)
							break;

						// TODO: Attempt to coerce args to formal param types of overloaded methods



						if (mi == null)
							throw new CseLogicException(CseLogicExceptionType.METHOD_CALL_AMBIGUOUS, methName);

						break;
				}
			}
			catch (AmbiguousMatchException) {
				throw new CseLogicException(CseLogicExceptionType.METHOD_CALL_AMBIGUOUS, methName);
			}
			catch (CseLogicException) {
				throw;
			}
			catch {
				throw new CseLogicException(CseLogicExceptionType.METHOD_EXISTS_BUT_CANT_BE_INVOKED, methName);
			}

			if (mi == null) {
				throw new CseLogicException(CseLogicExceptionType.METHOD_EXISTS_BUT_CANT_BE_INVOKED, methName);
			}
			else {
				dynamic result = mi.Invoke(environment.Value, GetObjArgs(args));

				CseObject xo = new CseObject(result);
				xo.CompileTimeType = mi.ReturnType;

				if (args != null) {
					foreach (CseObject arg in args) {
						if (arg.CallMod != CallArgMod.VAL) {
							AssignExp.Parse(arg.EnvChain, arg.EnvNames, arg.EnvIndices, arg.Value);
						}
					}
				}

				return xo;
			}
		}

Usage Example

Example #1
0
        ///
        /// <summary>
        ///
        /// </summary>
        ///
        public static dynamic Invoke(dynamic lambda, object[] args)
        {
            //dynamic clambda = new Func<int, int>(lambda.Data);
            return(MethodExp.Parse(CsEval.evalEnvironment, "Foo", new List <CseObject>()
            {
                new CseObject(lambda)
            }).Value);


            //dynamic result = null;

            //switch (args.Length) {
            //   case 1:
            //      result = lambda.Data(args[0]);
            //      break;
            //   case 2:
            //      result = lambda.Data(args[0], args[1]);
            //      break;
            //}

            //return value;
        }