private IExpr ResolveMethodCall(string fullname, IExpr[] args) { string cls, method; int idx = fullname.LastIndexOf('.'); if (idx > 0) { cls = fullname.Substring(0, idx); method = fullname.Substring(idx+1); } else { cls = ""; method = fullname; } // Fill out the argument types Type[] argTypes = new Type[args.Length]; for (int i=0; i < args.Length; i++) { argTypes[i] = XmlUtil.GetTypeFromTypeCode(args[i].GetTypeCode()); } // See if this is a function within the Code element Type cType=null; bool bCodeFunction = false; if (cls == "" || cls.ToLower() == "code") { cType = idLookup.CodeClassType; // get the code class type if (cType != null) { if (XmlUtil.GetMethod(cType, method, argTypes) == null) cType = null; // try for the method in the instance else bCodeFunction = true; } if (cls != "" && !bCodeFunction) throw new ParserException(string.Format("{0} is not a Code method. Verify the name of the method and its arguments match an existing code function.", method)); } // See if this is a function within the instance classes ReportClass rc=null; if (cType == null) { rc = idLookup.LookupInstance(cls); // is this an instance variable name? if (rc == null) { cType=idLookup.LookupType(cls); // no, must be a static class reference } else { cType= idLookup.LookupType(rc.ClassName); // yes, use the classname of the ReportClass } } string syscls=null; if (cType == null) { // ok try for some of the system functions switch(cls) { case "Math": syscls = "System.Math"; break; case "String": syscls = "System.String"; break; case "Convert": syscls = "System.Convert"; break; case "Financial": syscls = "fyiReporting.RDL.Financial"; break; default: syscls = "fyiReporting.RDL.VBFunctions"; break; } if (syscls != null) { cType = Type.GetType(syscls, false, true); } } if (cType == null) { string err; if (cls == null || cls.Length == 0) err = String.Format("Function {0} is not known.", method); else err = String.Format("Class {0} is not known.", cls); throw new ParserException(err); } IExpr result=null; MethodInfo mInfo = XmlUtil.GetMethod(cType, method, argTypes); if (mInfo == null) { string err; if (cls == null || cls.Length == 0) err = String.Format("Function '{0}' is not known.", method); else err = String.Format("Function '{0}' of class '{1}' is not known.", method, cls); throw new ParserException(err); } // when nullable object (e.g. DateTime?, int?,...) // we need to get the underlying type Type t = mInfo.ReturnType; if (Type.GetTypeCode(t) == TypeCode.Object) { try { t = Nullable.GetUnderlyingType(t); } catch { } // ok if it fails; must not be nullable object } // obtain the TypeCode TypeCode tc = Type.GetTypeCode(t); if (bCodeFunction) result = new FunctionCode(method, args, tc); else if (syscls != null) result = new FunctionSystem(syscls, method, args, tc); else if (rc == null) result = new FunctionCustomStatic(idLookup.CMS, cls, method, args, tc); else result = new FunctionCustomInstance(rc, method, args, tc); return result; }
private IExpr ResolveMethodCall(string fullname, IExpr[] args) { string cls, method; int idx = fullname.LastIndexOf('.'); if (idx > 0) { cls = fullname.Substring(0, idx); method = fullname.Substring(idx + 1); } else { cls = ""; method = fullname; } // Fill out the argument types Type[] argTypes = new Type[args.Length]; for (int i = 0; i < args.Length; i++) { argTypes[i] = XmlUtil.GetTypeFromTypeCode(args[i].GetTypeCode()); } // See if this is a function within the Code element Type cType = null; bool bCodeFunction = false; if (cls == "" || cls.ToLower() == "code") { cType = idLookup.CodeClassType; // get the code class type if (cType != null) { if (cType.GetMethod(method, argTypes) == null) { cType = null; // try for the method in the instance } else { bCodeFunction = true; } } if (cls != "" && !bCodeFunction) { throw new ParserException(string.Format("{0} is not a Code method. Verify the name of the method and its arguments match an existing code function.", method)); } } // See if this is a function within the instance classes ReportClass rc = null; if (cType == null) { rc = idLookup.LookupInstance(cls); // is this an instance variable name? if (rc == null) { cType = idLookup.LookupType(cls); // no, must be a static class reference } else { cType = idLookup.LookupType(rc.ClassName); // yes, use the classname of the ReportClass } } string syscls = null; if (cType == null) { // ok try for some of the system functions switch (cls) { case "Math": syscls = "System.Math"; break; case "String": syscls = "System.String"; break; case "Convert": syscls = "System.Convert"; break; case "Financial": syscls = "fyiReporting.RDL.Financial"; break; default: syscls = "fyiReporting.RDL.VBFunctions"; break; } if (syscls != null) { cType = Type.GetType(syscls); } } if (cType == null) { string err; if (cls == null || cls.Length == 0) { err = String.Format("Function {0} is not known.", method); } else { err = String.Format("Class {0} is not known.", cls); } throw new ParserException(err); } IExpr result = null; // MethodInfo mInfo = cType.GetMethod(method, BindingFlags.,binder, argTypes, modifiers); MethodInfo mInfo = cType.GetMethod(method, argTypes); if (mInfo == null) { string err; if (cls == null || cls.Length == 0) { err = String.Format("Function '{0}' is not known.", method); } else { err = String.Format("Function '{0}' of class '{1}' is not known.", method, cls); } throw new ParserException(err); } TypeCode tc = Type.GetTypeCode(mInfo.ReturnType); if (bCodeFunction) { result = new FunctionCode(method, args, tc); } else if (syscls != null) { result = new FunctionSystem(syscls, method, args, tc); } else if (rc == null) { result = new FunctionCustomStatic(idLookup.CMS, cls, method, args, tc); } else { result = new FunctionCustomInstance(rc, method, args, tc); } return(result); }