context: /*
   
   * Author:	Bob Limnor (info@limnor.com)
   * Project: Limnor Studio
   * Item:	Visual Expression Display and Edit
   * License: GNU General Public License v3.0
   
   */
  using System;
  using System.Collections.Generic;
  using System.Text;
  using MathExp;
  using System.ComponentModel;
  using System.Xml;
  using System.Reflection;
  using VPL;
  
  namespace MathExp.RaisTypes
  {
  	/// <summary>
  	/// reference a method, not defining it.
  	/// </summary>
  	public class MethodRef : IXmlNodeSerializable
  	{
  		//these two fields identify the method to be called
  		private ObjectRef _methodOwnerObjectRef;
  		private string _methodName;
  		//for a customer method the method id uniquely identifies it
  		private int _methodId;
  		//these two fields come from the method.
  		//they should be set when the method is selected.
  		//they are saved
  		private ParameterDef[] _parameters;
  		private RaisDataType _retType;
  		public MethodRef()
  		{
  		}
  		public MethodRef(ObjectRef owner, string name, int id, ParameterDef[] parameters, RaisDataType returnType)
  		{
  			_methodOwnerObjectRef = owner;
  			_methodName = name;
  			_methodId = id;
  			_parameters = parameters;
  			_retType = returnType;
  		}
  		public override string ToString()
  		{
  			if (_methodName == XmlSerialization.CONSTRUCTOR_METHOD)
  				return "new " + MethodOwnerName;
  			return MethodOwnerName + "." + MethodName;
  		}
  		[Browsable(false)]
  		public int MethodID
  		{
  			get
  			{
  				return _methodId;
  			}
  			set
  			{
  				_methodId = value;
  			}
  		}
  		[Browsable(false)]
  		public ObjectRef MethodOwner
  		{
  			get
  			{
  				return _methodOwnerObjectRef;
  			}
  			set
  			{
  				_methodOwnerObjectRef = value;
  			}
  		}
  		public string MethodOwnerName
  		{
  			get
  			{
  				if (_methodOwnerObjectRef != null)
  					return _methodOwnerObjectRef.Name;
  				return "";
  			}
  		}
  		public string MethodName
  		{
  			get
  			{
  				if (string.IsNullOrEmpty(_methodName))
  					return "";
  				return _methodName;
  			}
  			set
  			{
  				_methodName = value;
  			}
  		}
  		public int ParameterCount
  		{
  			get
  			{
  				if (_parameters == null)
  					return 0;
  				return _parameters.Length;
  			}
  		}
  		[ReadOnly(true)]
  		public ParameterDef[] Parameters
  		{
  			get
  			{
  				return _parameters;
  			}
  			set
  			{
  				_parameters = value;
  			}
  		}
  		[Browsable(false)]
  		public RaisDataType ReturnType
  		{
  			get
  			{
  				if (_retType == null)
  					_retType = new RaisDataType(typeof(void));
  				return _retType;
  			}
  			set
  			{
  				_retType = value;
  			}
  		}
  		/// <summary>
  		/// find out whether this type is a static method
  		/// </summary>
  		[Browsable(false)]
  		public bool IsStatic
  		{
  			get
  			{
  				if (string.IsNullOrEmpty(_methodName))
  					throw new MathException("Accessing IsStatic with empty method name");
  				if (_methodOwnerObjectRef == null)
  					throw new MathException("Accessing IsStatic with null owner");
  
  				if (_methodOwnerObjectRef.Type == ObjectRefType.Type)
  					return true;
  				if (_methodOwnerObjectRef.Type == ObjectRefType.Field || _methodOwnerObjectRef.Type == ObjectRefType.Property)
  				{
  					if (_methodOwnerObjectRef.Owner.Type == ObjectRefType.XPath)
  					{
  						return _methodOwnerObjectRef.Owner.IsStatic;
  					}
  
  					throw new MathException(XmlSerialization.FormatString("Accessing IsStatic for Field. Owner type {0} not implemented", _methodOwnerObjectRef.Owner.Type));
  				}
  				if (_methodOwnerObjectRef.Type == ObjectRefType.XPath)
  				{
  					XmlDocument doc = _methodOwnerObjectRef.GetXmlDocument();
  					if (doc == null)
  						throw new MathException("Accessing IsStatic with null document");
  					XmlNode prj = XmlSerialization.GetProjectNode(doc);
  					if (prj == null)
  						throw new MathException("Accessing IsStatic with null project");
  					XmlNode ownNode = prj.SelectSingleNode(_methodOwnerObjectRef.XPath);
  					if (ownNode == null)
  						throw new MathException(XmlSerialization.FormatString("Accessing IsStatic with invalid xpath {0}", _methodOwnerObjectRef.XPath));
  					if (_methodName == XmlSerialization.CONSTRUCTOR_METHOD)
  						return true;
  					XmlNode methodNode = ownNode.SelectSingleNode(XmlSerialization.FormatString("{0}[@{1}='{2}']",
  						XmlSerialization.XML_METHOD, XmlSerialization.XMLATT_NAME, _methodName));
  					if (methodNode == null)
  					{
  						Type t = XmlSerialization.GetObjectLibType(ownNode);
  						if (t == null)
  							throw new MathException(XmlSerialization.FormatString("Accessing IsStatic with valid xpath {0} but method name {1} not found and owner library type not found", _methodOwnerObjectRef.XPath, _methodName));
  						MethodInfo mif = t.GetMethod(_methodName);
  						if (mif == null)
  							throw new MathException(XmlSerialization.FormatString("Accessing IsStatic with valid xpath {0} but method name {1} not found in owner library type {2}", _methodOwnerObjectRef.XPath, _methodName, t.Name));
  						return mif.IsStatic;
  					}
  					else
  					{
  						return XmlSerialization.GetAttributeBool(methodNode, XmlSerialization.XMLATT_STATIC);
  					}
  				}
  				throw new MathException(XmlSerialization.FormatString("Accessing IsStatic: type not implemented: {0}", _methodOwnerObjectRef.Type));
  			}
  		}
  		private void getSignature(MethodInfo mi)
  		{
  			_retType = new RaisDataType(mi.ReturnType);
  			ParameterInfo[] ps = mi.GetParameters();
  			if (ps != null && ps.Length > 0)
  			{
  				_parameters = new ParameterDef[ps.Length];
  				for (int i = 0; i < ps.Length; i++)
  				{
  					_parameters[i] = new ParameterDef(ps[i].ParameterType, ps[i].Name);
  				}
  			}
  		}
  		/// <summary>
  		/// retrieve _retyrnType and parameters
  		/// </summary>
  		private void getSignature()
  		{
  			if (string.IsNullOrEmpty(_methodName))
  				throw new MathException("Accessing getSignature with empty method name");
  			if (_methodOwnerObjectRef == null)
  				throw new MathException("Accessing getSignature with null owner");
  
  
gt: 			if (_methodOwnerObjectRef.Type == ObjectRefType.Type)