Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        object InitializeExtensionObject(Tuple <XPathModuleInfo, Type> info, XmlResolver resolver)
        {
            object instance = Activator.CreateInstance(info.Item2);

            XPathModuleInfo moduleInfo = info.Item1;

            if (moduleInfo == null)
            {
                var xpathFn = instance as extensions.XPathFunctions;

                if (xpathFn != null)
                {
                    xpathFn.resolver = resolver;
                }
            }
            else if (moduleInfo.Dependencies.Count > 0)
            {
                object[] args = new object[info.Item1.Dependencies.Count];

                for (int i = 0; i < info.Item1.Dependencies.Count; i++)
                {
                    XPathDependencyInfo dependency = info.Item1.Dependencies[i];

                    if (dependency.Type == typeof(XPathItemFactory))
                    {
                        args[i] = this.Processor.ItemFactory;
                        continue;
                    }

                    if (dependency.Type == typeof(XmlResolver))
                    {
                        args[i] = resolver;
                        continue;
                    }

                    if (dependency.Type == typeof(IXsltProcessor))
                    {
                        args[i] = this.Processor;
                        continue;
                    }

                    args[i] = dependency.Type.IsValueType ?
                              Activator.CreateInstance(dependency.Type)
                  : null;
                }

                info.Item2.GetMethod("Initialize").Invoke(instance, args);
            }

            return(instance);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        CodeMemberMethod GenerateCallMethod(XPathFunctionInfo[] functions, int minArgs, int maxArgs, CodeExpression processorRef, CodeMemberMethod initializeMethod)
        {
            XPathFunctionInfo mostParameters = functions.OrderByDescending(f => f.Parameters.Count).First();
            XPathModuleInfo   module         = mostParameters.Module;

            var argsParam = new CodeParameterDeclarationExpression(typeof(IXdmEnumerator[]), "arguments");

            var callMethod = new CodeMemberMethod {
                Name       = "Call",
                Attributes = MemberAttributes.Public | MemberAttributes.Override,
                ReturnType = new CodeTypeReference(typeof(IXdmEnumerator)),
                Parameters =
                {
                    argsParam,
                    new CodeParameterDeclarationExpression(typeof(DynamicContext), "context")
                }
            };

            var argumentsRef = new CodeVariableReferenceExpression(callMethod.Parameters[0].Name);

            CodeExpression moduleRef;

            if (module.TypeIsStatic)
            {
                moduleRef = new CodeTypeReferenceExpression(module.Type);
            }
            else
            {
                var moduleVar = new CodeVariableDeclarationStatement {
                    Name           = "module",
                    Type           = new CodeTypeReference(module.Type),
                    InitExpression = new CodeObjectCreateExpression(module.Type)
                };

                callMethod.Statements.Add(moduleVar);

                moduleRef = new CodeVariableReferenceExpression(moduleVar.Name);

                if (initializeMethod != null)
                {
                    callMethod.Statements.Add(new CodeMethodInvokeExpression {
                        Method     = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), initializeMethod.Name),
                        Parameters = { moduleRef }
                    });
                }
            }

            CodeStatementCollection currentBlock = callMethod.Statements;
            var paramRef = new List <CodeExpression>();

            for (int pos = 0; pos <= maxArgs; pos++)
            {
                if (pos > 0)
                {
                    XPathSequenceType paramInfo = mostParameters.Parameters[pos - 1].Type;

                    var paramVar = new CodeVariableDeclarationStatement {
                        Name           = "p" + pos,
                        Type           = new CodeTypeReference(paramInfo.ClrType),
                        InitExpression = TransformInput(argumentsRef, pos, paramInfo)
                    };

                    currentBlock.Add(paramVar);

                    paramRef.Add(new CodeVariableReferenceExpression(paramVar.Name));
                }

                if (pos >= minArgs)
                {
                    XPathFunctionInfo fn = functions[pos - minArgs];

                    CodeConditionStatement ifElse = null;

                    if (minArgs != maxArgs &&
                        pos < maxArgs)
                    {
                        ifElse = new CodeConditionStatement {
                            Condition = new CodeBinaryOperatorExpression {
                                Left     = new CodePropertyReferenceExpression(argumentsRef, "Length"),
                                Operator = CodeBinaryOperatorType.ValueEquality,
                                Right    = new CodePrimitiveExpression(pos)
                            }
                        };

                        currentBlock.Add(ifElse);
                        currentBlock = ifElse.TrueStatements;
                    }

                    var functionInvoke = new CodeMethodInvokeExpression {
                        Method = new CodeMethodReferenceExpression(moduleRef, fn.Method.Name)
                    };

                    functionInvoke.Parameters.AddRange(paramRef.ToArray());

                    CodeExpression returnExpr;

                    if (!fn.ReturnType.IsEmptySequence)
                    {
                        returnExpr = TransformOutput(functionInvoke, fn.ReturnType, processorRef);
                    }
                    else
                    {
                        currentBlock.Add(functionInvoke);

                        returnExpr = new CodePropertyReferenceExpression {
                            PropertyName = "INSTANCE",
                            TargetObject = new CodeTypeReferenceExpression(typeof(EmptyEnumerator))
                        };
                    }

                    currentBlock.Add(new CodeMethodReturnStatement(returnExpr));

                    if (ifElse != null)
                    {
                        currentBlock = ifElse.FalseStatements;
                    }
                }
            }

            return(callMethod);
        }
Ejemplo n.º 7
0
        Tuple <CodeTypeDeclaration, CodeTypeDeclaration> GenerateFunctionType(XPathFunctionInfo[] functions)
        {
            XPathFunctionInfo first           = functions.First();
            XPathFunctionInfo leastParameters = functions.OrderBy(f => f.Parameters.Count).First();
            XPathFunctionInfo mostParameters  = functions.OrderByDescending(f => f.Parameters.Count).First();
            XPathModuleInfo   module          = first.Module;
            int minArgs = leastParameters.Parameters.Count;
            int maxArgs = mostParameters.Parameters.Count;

            CodeExpression thisRef = new CodeThisReferenceExpression();

            var processorField = new CodeMemberField {
                Name = "_processor",
                Type = new CodeTypeReference(typeof(SaxonProcessor))
            };

            var funcNameField = new CodeMemberField {
                Name           = "_FunctionName",
                Type           = new CodeTypeReference(typeof(QName)),
                InitExpression = new CodeObjectCreateExpression(
                    typeof(QName),
                    new CodePrimitiveExpression(module.Namespace),
                    new CodePrimitiveExpression(first.Name)
                    )
            };

            var argTypesField = new CodeMemberField {
                Name           = "_ArgumentTypes",
                Type           = new CodeTypeReference(typeof(XdmSequenceType[])),
                InitExpression = new CodeArrayCreateExpression(
                    typeof(XdmSequenceType),
                    mostParameters.Parameters.Select(p =>
                                                     new CodeObjectCreateExpression(
                                                         typeof(XdmSequenceType),
                                                         GetXdmItemTypeExpression(p.Type.ItemType),
                                                         new CodePrimitiveExpression(GetOcurrenceIndicator(p.Type.Cardinality))
                                                         )).ToArray()
                    )
            };

            var resultTypesField = new CodeMemberField {
                Name = "_resultTypes",
                Type = new CodeTypeReference(typeof(XdmSequenceType[]))
            };

            var resultTypesFieldInit = new CodeArrayCreateExpression {
                CreateType = resultTypesField.Type,
                Size       = functions.Length
            };

            for (int i = 0; i < functions.Length; i++)
            {
                XPathFunctionInfo function = functions[i];

                resultTypesFieldInit.Initializers.Add(

                    // Using item()? instead of empty-sequence()

                    (function.ReturnType.IsEmptySequence) ?

                    new CodeObjectCreateExpression(
                        typeof(XdmSequenceType),
                        new CodeFieldReferenceExpression(
                            new CodeTypeReferenceExpression(typeof(XdmAnyItemType)),
                            "Instance"
                            ),
                        new CodePrimitiveExpression(GetOcurrenceIndicator(XPathSequenceCardinality.ZeroOrOne))
                        )

                  : new CodeObjectCreateExpression(
                        typeof(XdmSequenceType),
                        GetXdmItemTypeExpression(function.ReturnType.ItemType),
                        new CodePrimitiveExpression(GetOcurrenceIndicator(function.ReturnType.Cardinality))
                        )
                    );
            }

            resultTypesField.InitExpression = resultTypesFieldInit;

            var defClass = new CodeTypeDeclaration {
                Name       = first.Method.Name + "Function",
                Attributes = MemberAttributes.Public,
                BaseTypes  = { typeof(ExtensionFunctionDefinition) },
                Members    =
                {
                    processorField,
                    funcNameField,
                    argTypesField,
                    resultTypesField,
                    new CodeConstructor {
                        Attributes = MemberAttributes.Public,
                        Parameters =
                        {
                            new CodeParameterDeclarationExpression(processorField.Type,            "processor")
                        },
                        Statements =
                        {
                            new CodeAssignStatement(
                                new CodeFieldReferenceExpression(thisRef, processorField.Name),
                                new CodeVariableReferenceExpression("processor")
                                )
                        }
                    },
                    new CodeMemberProperty {
                        Name          = "FunctionName",
                        Type          = funcNameField.Type,
                        Attributes    = MemberAttributes.Public | MemberAttributes.Override,
                        HasGet        = true,
                        GetStatements =
                        {
                            new CodeMethodReturnStatement(new CodeFieldReferenceExpression(thisRef,funcNameField.Name))
                        }
                    },
                    new CodeMemberProperty {
                        Name          = "ArgumentTypes",
                        Type          = argTypesField.Type,
                        Attributes    = MemberAttributes.Public | MemberAttributes.Override,
                        HasGet        = true,
                        GetStatements =
                        {
                            new CodeMethodReturnStatement(new CodeFieldReferenceExpression(thisRef,argTypesField.Name))
                        }
                    },
                    new CodeMemberProperty {
                        Name          = "MaximumNumberOfArguments",
                        Type          = new CodeTypeReference(typeof(int)),
                        Attributes    = MemberAttributes.Public | MemberAttributes.Override,
                        HasGet        = true,
                        GetStatements =
                        {
                            new CodeMethodReturnStatement(new CodePrimitiveExpression(maxArgs))
                        }
                    },
                    new CodeMemberProperty {
                        Name          = "MinimumNumberOfArguments",
                        Type          = new CodeTypeReference(typeof(int)),
                        Attributes    = MemberAttributes.Public | MemberAttributes.Override,
                        HasGet        = true,
                        GetStatements =
                        {
                            new CodeMethodReturnStatement(new CodePrimitiveExpression(minArgs))
                        }
                    },
                    GenerateResultTypeMethod(thisRef,                                              resultTypesField)
                }
            };

            if (first.HasSideEffects)
            {
                defClass.Members.Add(new CodeMemberProperty {
                    Name          = "HasSideEffects",
                    Type          = new CodeTypeReference(typeof(bool)),
                    Attributes    = MemberAttributes.Public | MemberAttributes.Override,
                    HasGet        = true,
                    GetStatements =
                    {
                        new CodeMethodReturnStatement(new CodePrimitiveExpression(true))
                    }
                });
            }

            var callClass = new CodeTypeDeclaration {
                Name       = defClass.Name + "Call",
                Attributes = MemberAttributes.Assembly,
                BaseTypes  =
                {
                    new CodeTypeReference(typeof(ExtensionFunctionCall))
                },
                Members =
                {
                    processorField,
                    new CodeConstructor {
                        Attributes = MemberAttributes.Public,
                        Parameters =
                        {
                            new CodeParameterDeclarationExpression(processorField.Type,"processor")
                        },
                        Statements =
                        {
                            new CodeAssignStatement(
                                new CodeFieldReferenceExpression(thisRef, processorField.Name),
                                new CodeVariableReferenceExpression("processor")
                                )
                        }
                    }
                }
            };

            CodeMemberMethod initializeMethod = null;

            if (!module.TypeIsStatic &&
                module.Dependencies.Count > 0)
            {
                CodeExpression staticBaseUriExpr = null;

                if (module.Dependencies.Any(d => d.Type == typeof(XmlResolver)))
                {
                    var staticBaseUriField = new CodeMemberField {
                        Name = "_staticBaseUri",
                        Type = new CodeTypeReference(typeof(Uri))
                    };

                    callClass.Members.Add(staticBaseUriField);

                    var staticContextParam = new CodeParameterDeclarationExpression(typeof(StaticContext), "context");

                    staticBaseUriExpr = new CodeFieldReferenceExpression(thisRef, staticBaseUriField.Name);

                    callClass.Members.Add(new CodeMemberMethod {
                        Name       = "SupplyStaticContext",
                        Attributes = MemberAttributes.Public | MemberAttributes.Override,
                        Parameters =
                        {
                            staticContextParam
                        },
                        Statements =
                        {
                            new CodeAssignStatement {
                                Left  = staticBaseUriExpr,
                                Right = new CodePropertyReferenceExpression{
                                    PropertyName = "BaseUri",
                                    TargetObject = new CodeVariableReferenceExpression(staticContextParam.Name)
                                }
                            }
                        }
                    });
                }

                initializeMethod = GenerateInitialize(module, new CodeFieldReferenceExpression(thisRef, processorField.Name), staticBaseUriExpr);

                callClass.Members.Add(initializeMethod);
            }

            callClass.Members.Add(GenerateCallMethod(functions, minArgs, maxArgs, new CodeFieldReferenceExpression(thisRef, processorField.Name), initializeMethod));

            defClass.Members.Add(
                new CodeMemberMethod {
                Name       = "MakeFunctionCall",
                Attributes = MemberAttributes.Public | MemberAttributes.Override,
                ReturnType = new CodeTypeReference(typeof(ExtensionFunctionCall)),
                Statements =
                {
                    new CodeMethodReturnStatement(
                        new CodeObjectCreateExpression(
                            callClass.Name,
                            new CodeFieldReferenceExpression(thisRef, processorField.Name)
                            )
                        )
                }
            }
                );

            return(Tuple.Create(defClass, callClass));
        }