internal XPathFunctionInfo(MethodInfo method, XPathModuleInfo module) { if (method == null) { throw new ArgumentNullException("method"); } if (method.ContainsGenericParameters) { throw new ArgumentException("Methods that accept type parameters cannot be used as module functions.", "method"); } if (method.GetParameters().Any(p => p.IsOut)) { throw new ArgumentException("Methods with out parmeters cannot be used as module functions.", "method"); } if (module == null) { throw new ArgumentNullException("module"); } this._Method = method; this._Module = module; if (this.Module.HasModuleAttribute) { this.functionAttr = Attribute.GetCustomAttribute(this.Method, typeof(XPathFunctionAttribute)) as XPathFunctionAttribute; } }
internal XPathFunctionInfo(MethodInfo method, XPathModuleInfo module) { if (method == null) throw new ArgumentNullException("method"); if (method.ContainsGenericParameters) throw new ArgumentException("Methods that accept type parameters cannot be used as module functions.", "method"); if (method.GetParameters().Any(p => p.IsOut)) throw new ArgumentException("Methods with out parmeters cannot be used as module functions.", "method"); if (module == null) throw new ArgumentNullException("module"); this._Method = method; this._Module = module; if (this.Module.HasModuleAttribute) { this.functionAttr = Attribute.GetCustomAttribute(this.Method, typeof(XPathFunctionAttribute)) as XPathFunctionAttribute; } }
static CodeTypeDeclaration GenerateType(XPathModuleInfo module) { var type = new CodeTypeDeclaration { Name = module.Type.FullName.Replace('.', '_') + "_extobj", IsClass = true, TypeAttributes = TypeAttributes.Public, CustomAttributes = { new CodeAttributeDeclaration( new CodeTypeReference(typeof(DebuggerNonUserCodeAttribute)) ) } }; CodeExpression moduleExpr; if (module.TypeIsStatic) { moduleExpr = new CodeTypeReferenceExpression(module.Type); } else { var moduleField = new CodeMemberField { Name = "module", Type = new CodeTypeReference(module.Type), InitExpression = new CodeObjectCreateExpression(module.Type) }; type.Members.Add(moduleField); moduleExpr = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), moduleField.Name); if (module.Dependencies.Count > 0) { type.Members.Add(GenerateInitialize(module, moduleExpr)); } } foreach (XPathFunctionInfo function in module.Functions) { type.Members.Add(GenerateFunction(function, moduleExpr)); } return type; }
static CodeMemberMethod GenerateInitialize(XPathModuleInfo module, CodeExpression moduleExpr) { var initializeMethod = new CodeMemberMethod { Name = "Initialize", Attributes = MemberAttributes.Public | MemberAttributes.Final }; for (int i = 0; i < module.Dependencies.Count; i++) { XPathDependencyInfo dependency = module.Dependencies[i]; initializeMethod.Parameters.Add(new CodeParameterDeclarationExpression { Type = new CodeTypeReference(dependency.Type), Name = "d" + (i + 1).ToStringInvariant() }); var paramRef = new CodeVariableReferenceExpression(initializeMethod.Parameters[i].Name); initializeMethod.Statements.Add(new CodeAssignStatement { Left = new CodePropertyReferenceExpression(moduleExpr, dependency.Property.Name), Right = paramRef }); } return initializeMethod; }
CodeNamespace GenerateModuleTypes(XPathModuleInfo module, out string[] functionDefTypeNames) { var namespaceBuilder = new StringBuilder() .Append(typeof(IntegratedExtensionFunctionGenerator).Namespace) .Append(".modules.") .Append(module.Type.FullName.Replace('.', '_')) .Append("_functions"); var nspace = new CodeNamespace { Name = namespaceBuilder.ToString(), Imports = { new CodeNamespaceImport(typeof(Enumerable).Namespace), new CodeNamespaceImport(typeof(SaxonExtensions).Namespace) } }; var groupedByName = from f in module.Functions group f by f.Name; var functionDefNames = new List<string>(); foreach (var functions in groupedByName) { Tuple<CodeTypeDeclaration, CodeTypeDeclaration> funcDefAndCall = GenerateFunctionType(functions.ToArray()); nspace.Types.Add(funcDefAndCall.Item1); nspace.Types.Add(funcDefAndCall.Item2); functionDefNames.Add(nspace.Name + "." + funcDefAndCall.Item1.Name); } functionDefTypeNames = functionDefNames.ToArray(); return nspace; }
CodeMemberMethod GenerateInitialize(XPathModuleInfo module, CodeExpression processorRef, CodeExpression staticBaseUriExpr) { var initializeMethod = new CodeMemberMethod { Name = "Initialize", Attributes = MemberAttributes.Private | MemberAttributes.Final, Parameters = { new CodeParameterDeclarationExpression(module.Type, "module") } }; for (int i = 0; i < module.Dependencies.Count; i++) { XPathDependencyInfo dependency = module.Dependencies[i]; CodeExpression expr = null; if (dependency.Type == typeof(IXsltProcessor) || dependency.Type == typeof(IXQueryProcessor)) { expr = processorRef; } else if (dependency.Type == typeof(XPathItemFactory)) { expr = GetItemFactoryReference(processorRef); } else if (dependency.Type == typeof(XmlResolver)) { expr = new CodeObjectCreateExpression(typeof(XmlDynamicResolver), staticBaseUriExpr); } if (expr != null) { initializeMethod.Statements.Add(new CodeAssignStatement { Left = new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(initializeMethod.Parameters[0].Name), dependency.Property.Name ), Right = expr }); } } return initializeMethod; }