Microsoft.JScript.LateBinding.Call C# (CSharp) Method

Call() private method

private Call ( Binder binder, Object arguments, ParameterModifier modifiers, CultureInfo culture, String namedParameters, bool construct, bool brackets, VsaEngine engine ) : Object
binder Binder
arguments Object
modifiers System.Reflection.ParameterModifier
culture CultureInfo
namedParameters String
construct bool
brackets bool
engine Microsoft.JScript.Vsa.VsaEngine
return Object
      internal Object Call(Binder binder, Object[] arguments, ParameterModifier[] modifiers, CultureInfo culture,
                           String[] namedParameters, bool construct, bool brackets, VsaEngine engine){
        MemberInfo member = this.BindToMember(); //Do a GetMember call and remember the result of the lookup for next time around


        //On ScriptObjects, fields/properties pre-empt everything else. Call whatever is the value of the field/property. If it is junk, throw an exception.
        if (this.obj is ScriptObject || this.obj is GlobalObject){
          //Handle WithObjects that wrap COMObjects specially
          if (this.obj is WithObject){
            Object wob = ((WithObject)this.obj).contained_object;
            if (!(wob is ScriptObject)){
              IReflect irw = LateBinding.GetIRForObjectThatRequiresInvokeMember(wob, VsaEngine.executeForJSEE);
              if (irw != null)
                return LateBinding.CallCOMObject(irw, this.name, wob, binder, arguments, modifiers, culture, namedParameters, construct, brackets, engine);
            }
          }
          
          if (member is FieldInfo)
            return LateBinding.CallValue(((FieldInfo)member).GetValue(this.obj), arguments, construct, brackets, engine, this.obj, JSBinder.ob, null, null);
          else if (member is PropertyInfo && !(member is JSProperty)){ //JSProperty comes up when running the evaluator and using proper properties.
            if (!brackets){
              JSWrappedPropertyAndMethod propAndMethod = member as JSWrappedPropertyAndMethod;
              if (propAndMethod != null){
                BindingFlags flags = arguments == null || arguments.Length == 0
                  ? BindingFlags.InvokeMethod
                  : BindingFlags.InvokeMethod | BindingFlags.GetProperty;
                return propAndMethod.Invoke(this.obj, flags, JSBinder.ob, arguments, null);
              }
            }
            return LateBinding.CallValue(JSProperty.GetValue((PropertyInfo)member, this.obj, null), arguments, construct, brackets, engine, this.obj, JSBinder.ob, null, null);
          }
          //The code paths below happen because Lookup and Member set last_member. Without the cache, BindToMember will not deliver a MethodInfo.
          else if (member is MethodInfo){
            if (member is JSMethod)
              if (construct)
                return ((JSMethod)member).Construct(arguments);
              else
                return ((JSMethod)member).Invoke(this.obj, this.obj, (BindingFlags)0, JSBinder.ob, arguments, null);
            else{
              Type dt = member.DeclaringType;
              if (dt == typeof(Object))
                return LateBinding.CallMethod((MethodInfo)member, arguments, this.obj, binder, culture, namedParameters);
              else if (dt == typeof(String))
                return LateBinding.CallMethod((MethodInfo)member, arguments, Convert.ToString(this.obj), binder, culture, namedParameters);
              else if (Convert.IsPrimitiveNumericType(dt))
                return LateBinding.CallMethod((MethodInfo)member, arguments, Convert.CoerceT(this.obj, dt), binder, culture, namedParameters);
              else if (dt == typeof(Boolean))
                return LateBinding.CallMethod((MethodInfo)member, arguments, Convert.ToBoolean(this.obj), binder, culture, namedParameters);
              else if (dt == typeof(StringObject) || dt == typeof(BooleanObject) || dt == typeof(NumberObject) || brackets)
                return LateBinding.CallMethod((MethodInfo)member, arguments, Convert.ToObject(this.obj, engine), binder, culture, namedParameters);
              else if (dt == typeof(GlobalObject) && ((MethodInfo)member).IsSpecialName)
                return LateBinding.CallValue(((MethodInfo)member).Invoke(this.obj, null), arguments, construct, false, engine, this.obj, JSBinder.ob, null, null);
              else if (!(this.obj is ClassScope)){
                if (CustomAttribute.IsDefined(member, typeof(JSFunctionAttribute), false)){
                  FieldInfo f = LateBinding.SelectMember(this.last_members) as FieldInfo;
                  if (f != null){ //Field holds a closure, call the closure
                    Object obj = this.obj;
                    if (!(obj is Closure))
                      obj = f.GetValue(this.obj);
                    return LateBinding.CallValue(obj, arguments, construct, brackets, engine, this.obj, JSBinder.ob, null, null);
                  }
                }
                return LateBinding.CallValue(new BuiltinFunction(this.obj, (MethodInfo)member), arguments, construct, false, engine, this.obj, JSBinder.ob, null, null);
              }
            }
          }
        }

        MethodInfo meth = member as MethodInfo;
        if (meth != null) //Inside the evaluator, and dealing with an early bound method
          //Get here because of EvaluateAsLateBinding in Lookup and Member. BindToMember will not have set this.member to be a method
          return LateBinding.CallMethod(meth, arguments, this.obj, binder, culture, namedParameters);
        JSConstructor jscons = member as JSConstructor;
        if (jscons != null) //Inside the evaluator, and dealing with an early bound constructor
          return LateBinding.CallValue(jscons.cons, arguments, construct, brackets, engine, this.obj, JSBinder.ob, null, null);
        if (member is Type) //Inside the evaluator and dealing with early bound conversion
          return LateBinding.CallValue(member, arguments, construct, brackets, engine, this.obj, JSBinder.ob, null, null);
        if (member is ConstructorInfo) //Inside the evaluator, and dealing with an early bound constructor
          return LateBinding.CallOneOfTheMembers(new MemberInfo[]{this.last_member}, arguments, true, this.obj, binder, culture, namedParameters, engine);

        if (!construct && member is PropertyInfo){
          //Might be a parameterless property that results in an object that has a default method or default indexed property that can be called with the params
          //Need to special case this, otherwise the next if will end up calling the parameterless property getter, discarding the parameters
          if (((PropertyInfo)member).GetIndexParameters().Length == 0){
            Type rtype = ((PropertyInfo)member).PropertyType;
            if (rtype == typeof(Object)){
              MethodInfo getter = JSProperty.GetGetMethod((PropertyInfo)member, false);
              if (getter != null){
                Object ob = getter.Invoke(this.obj, null);
                return LateBinding.CallValue(ob, arguments, construct, brackets, engine, this.obj, JSBinder.ob, null, null);
              }
            }
            MemberInfo[] defaultMembers = TypeReflector.GetTypeReflectorFor(rtype).GetDefaultMembers();
            if (defaultMembers != null && defaultMembers.Length > 0){
              MethodInfo getter = JSProperty.GetGetMethod((PropertyInfo)member, false);
              if (getter != null){
                Object ob = getter.Invoke(this.obj, null);
                return LateBinding.CallOneOfTheMembers(defaultMembers, arguments, false, ob, binder, culture, namedParameters, engine);
              }
            }
          }
        }

        //Otherwise, if there are members, we give preference to constructors, methods and properties with matching formal parameter lists.
        if (this.last_members != null && this.last_members.Length > 0)
        {
          bool memberCalled;
          object retval = LateBinding.CallOneOfTheMembers(this.last_members, arguments, construct, this.obj, binder, culture, namedParameters, engine, out memberCalled);
          if (memberCalled)
            return retval;
          //Fall through if no suitable constructor or method or property getter because the value of (this.obj).(this.name) might contain a callable thing.
        }

        //If the object is an IDispatch(Ex) use InvokeMember to do the call
        //In all other cases we can assume that BindToMember has already found all the members that are to be found.
        IReflect ir = LateBinding.GetIRForObjectThatRequiresInvokeMember(this.obj, VsaEngine.executeForJSEE);
        if (ir != null)
          return LateBinding.CallCOMObject(ir, this.name, this.obj, binder, arguments, modifiers, culture, namedParameters, construct, brackets, engine);

        //If the object has a field or parameterless property called this.name, we have to try and call the value of that field or property
        Object value = LateBinding.GetMemberValue(this.obj, this.name, this.last_member, this.last_members);
        if (!(value is Missing))
          return LateBinding.CallValue(value, arguments, construct, brackets, engine, this.obj, JSBinder.ob, null, null);

        //Give up
        if (brackets)
          if (this.obj is IActivationObject)
            throw new JScriptException(JSError.ObjectExpected);
          else
            throw new JScriptException(JSError.OLENoPropOrMethod);
        else
          throw new JScriptException(JSError.FunctionExpected);
      }

Same methods

LateBinding::Call ( Object arguments, bool construct, bool brackets, VsaEngine engine ) : Object

Usage Example

 public static object CallMethod(string name, object thisob, object[] arguments, VsaEngine engine)
 {
     if (engine == null)
     {
         engine = VsaEngine.CreateEngine();
     }
     LateBinding binding = new LateBinding(name, thisob, true);
     return binding.Call(arguments, false, false, engine);
 }
All Usage Examples Of Microsoft.JScript.LateBinding::Call