Exemplo n.º 1
0
        static CodeExpression GetReturnExpression(XPathSequenceType sequenceType, CodeVariableReferenceExpression varExpr)
        {
            if (sequenceType.ClrType == typeof(void))
            {
                return(new CodePropertyReferenceExpression {
                    PropertyName = "EmptyIterator",
                    TargetObject = new CodeTypeReferenceExpression(typeof(ExtensionObjectConvert))
                });
            }

            string convertMethod = "ToInput";

            if (sequenceType.ItemType.KindIsNode)
            {
                convertMethod += "Node";
            }

            if (sequenceType.Cardinality == XPathSequenceCardinality.ZeroOrMore ||
                sequenceType.Cardinality == XPathSequenceCardinality.ZeroOrOne)
            {
                convertMethod += "OrEmpty";
            }

            CodeExpression returnExpr = new CodeMethodInvokeExpression {
                Method = new CodeMethodReferenceExpression {
                    MethodName   = convertMethod,
                    TargetObject = new CodeTypeReferenceExpression(typeof(ExtensionObjectConvert))
                },
                Parameters = { varExpr }
            };

            if (sequenceType.ItemType.Kind == XPathItemKind.Element ||
                sequenceType.ItemType.Kind == XPathItemKind.SchemaElement)
            {
                returnExpr = new CodeMethodInvokeExpression {
                    Method = new CodeMethodReferenceExpression {
                        MethodName   = "FirstElementOrSelf",
                        TargetObject = new CodeTypeReferenceExpression(typeof(ExtensionObjectConvert))
                    },
                    Parameters = { returnExpr }
                };
            }

            return(returnExpr);
        }
Exemplo n.º 2
0
        static Type GetReturnType(XPathSequenceType returnTypeInfo)
        {
            switch (returnTypeInfo.Cardinality)
            {
            default:
            case XPathSequenceCardinality.One:

                if (returnTypeInfo.ItemType.KindIsNode)
                {
                    return(typeof(XPathNavigator));
                }

                return(typeof(object));

            case XPathSequenceCardinality.ZeroOrOne:
            case XPathSequenceCardinality.ZeroOrMore:
                return(typeof(object));

            case XPathSequenceCardinality.OneOrMore:
                return(typeof(XPathNavigator[]));
            }
        }
Exemplo n.º 3
0
        static CodeExpression TransformOutput(CodeExpression functionResultRef, XPathSequenceType sequenceType, CodeExpression processorRef)
        {
            CodeExpression itemFactoryRef = GetItemFactoryReference(processorRef);

            CodeExpression expr = new CodeMethodInvokeExpression {
                Method = new CodeMethodReferenceExpression {
                    MethodName   = "ToXdmValue",
                    TargetObject = new CodeTypeReferenceExpression(typeof(SaxonExtensions))
                },
                Parameters =
                {
                    functionResultRef,
                    itemFactoryRef
                }
            };

            if (sequenceType.ItemType.Kind == XPathItemKind.Element ||
                sequenceType.ItemType.Kind == XPathItemKind.SchemaElement)
            {
                expr = new CodeMethodInvokeExpression {
                    Method = new CodeMethodReferenceExpression {
                        MethodName   = "FirstElementOrSelf",
                        TargetObject = new CodeTypeReferenceExpression(typeof(SaxonExtensions))
                    },
                    Parameters = { expr }
                };
            }

            return(new CodeMethodInvokeExpression {
                Method = new CodeMethodReferenceExpression {
                    MethodName = "GetXdmEnumerator",
                    TargetObject = new CodeTypeReferenceExpression(typeof(SaxonExtensions))
                },
                Parameters = { expr }
            });
        }
Exemplo n.º 4
0
        static CodeExpression GetArgumentExpression(XPathSequenceType paramTypeInfo, Type varType, CodeVariableReferenceExpression varExpr)
        {
            var convertTypeExpr = new CodeTypeReferenceExpression(typeof(ExtensionObjectConvert));

            CodeExpression argExpr = varExpr;

            if (paramTypeInfo.ClrType.IsAssignableFrom(varType))
            {
                return(argExpr);
            }

            MethodInfo convertMethod = typeof(ExtensionObjectConvert)
                                       .GetMethod("To" + paramTypeInfo.ClrType.Name, BindingFlags.Public | BindingFlags.Static, null, new[] { varType }, null);

            if (convertMethod != null)
            {
                return(new CodeMethodInvokeExpression {
                    Method = new CodeMethodReferenceExpression {
                        MethodName = convertMethod.Name,
                        TargetObject = convertTypeExpr,
                    },
                    Parameters = { argExpr }
                });
            }

            MethodInfo convertItemMethod = typeof(ExtensionObjectConvert)
                                           .GetMethod("To" + paramTypeInfo.ItemType.ClrType.Name, BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(XPathItem) }, null);

            CodeExpression convertItemExpr = (convertItemMethod != null) ?
                                             new CodeMethodReferenceExpression(convertTypeExpr, convertItemMethod.Name)
            : null;

            if (paramTypeInfo.ClrTypeIsEnumerable)
            {
                CodeMethodInvokeExpression methodExpr;

                argExpr = methodExpr = new CodeMethodInvokeExpression {
                    Method = new CodeMethodReferenceExpression {
                        MethodName    = "ToEnumerable",
                        TypeArguments = { paramTypeInfo.ItemType.ClrType },
                        TargetObject  = convertTypeExpr
                    },
                    Parameters = { argExpr }
                };

                if (convertItemExpr != null)
                {
                    methodExpr.Parameters.Add(convertItemExpr);
                }

                if (paramTypeInfo.ClrType.IsArray)
                {
                    argExpr = new CodeMethodInvokeExpression {
                        Method = new CodeMethodReferenceExpression {
                            MethodName    = "ToArray",
                            TypeArguments = { paramTypeInfo.ItemType.ClrType },
                            TargetObject  = new CodeTypeReferenceExpression(typeof(Enumerable))
                        },
                        Parameters = { argExpr }
                    };
                }
            }
            else if (paramTypeInfo.ClrTypeIsNullableValueType)
            {
                CodeMethodInvokeExpression methodExpr;

                argExpr = methodExpr = new CodeMethodInvokeExpression {
                    Method = new CodeMethodReferenceExpression {
                        MethodName    = "ToNullableValueType",
                        TypeArguments = { paramTypeInfo.ItemType.ClrType },
                        TargetObject  = convertTypeExpr
                    },
                    Parameters = { argExpr }
                };

                if (convertItemExpr != null)
                {
                    methodExpr.Parameters.Add(convertItemExpr);
                }
            }
            else
            {
                CodeMethodInvokeExpression methodExpr;

                argExpr = methodExpr = new CodeMethodInvokeExpression {
                    Method = new CodeMethodReferenceExpression {
                        MethodName    = "ToOutput",
                        TypeArguments = { paramTypeInfo.ClrType },
                        TargetObject  = convertTypeExpr
                    },
                    Parameters = { argExpr }
                };

                if (convertItemExpr != null &&
                    paramTypeInfo.ClrType == paramTypeInfo.ItemType.ClrType)
                {
                    methodExpr.Parameters.Add(convertItemExpr);
                }
            }

            return(argExpr);
        }
Exemplo n.º 5
0
        static Type GetParameterType(XPathSequenceType paramTypeInfo)
        {
            switch (paramTypeInfo.Cardinality)
            {
            case XPathSequenceCardinality.One:

                if (paramTypeInfo.ItemType.Kind == XPathItemKind.AnyItem)
                {
                    return(typeof(object));
                }

                if (paramTypeInfo.ItemType.KindIsNode)
                {
                    return(typeof(XPathNavigator));
                }

                switch (Type.GetTypeCode(paramTypeInfo.ItemType.ClrType))
                {
                default:
                case TypeCode.String:
                case TypeCode.Char:
                case TypeCode.Object:
                    return(typeof(string));

                case TypeCode.Boolean:
                    return(typeof(bool));

                case TypeCode.Byte:
                    return(typeof(byte));

                case TypeCode.DateTime:
                    return(typeof(DateTime));

                case TypeCode.Decimal:
                    return(typeof(decimal));

                case TypeCode.Double:
                    return(typeof(double));

                case TypeCode.Int16:
                    return(typeof(Int16));

                case TypeCode.Int32:
                    return(typeof(Int32));

                case TypeCode.Int64:
                    return(typeof(Int64));

                case TypeCode.SByte:
                    return(typeof(SByte));

                case TypeCode.Single:
                    return(typeof(Single));

                case TypeCode.UInt16:
                    return(typeof(UInt16));

                case TypeCode.UInt32:
                    return(typeof(UInt32));

                case TypeCode.UInt64:
                    return(typeof(UInt64));
                }

            default:
                return(typeof(XPathNodeIterator));
            }
        }
Exemplo n.º 6
0
        static CodeMemberMethod GenerateFunction(XPathFunctionInfo function, CodeExpression moduleExpr)
        {
            string name = function.Name;

            MemberAttributes methodAttributes = MemberAttributes.Public;

            if (name.Contains('-'))
            {
                name             = name.Replace('-', '_');
                methodAttributes = MemberAttributes.Family;
            }

            methodAttributes |= MemberAttributes.Final;

            Type procReturnType = GetReturnType(function.ReturnType);

            var codeMethod = new CodeMemberMethod {
                Name       = name,
                Attributes = methodAttributes,
                ReturnType = new CodeTypeReference(procReturnType),
            };

            var methodInvoke = new CodeMethodInvokeExpression {
                Method = new CodeMethodReferenceExpression {
                    MethodName   = function.Method.Name,
                    TargetObject = moduleExpr
                }
            };

            for (int i = 0; i < function.Parameters.Count; i++)
            {
                XPathSequenceType paramTypeInfo = function.Parameters[i].Type;

                Type procParamType = GetParameterType(paramTypeInfo);

                var paramDecl = new CodeParameterDeclarationExpression {
                    Name = "p" + i.ToStringInvariant(),
                    Type = new CodeTypeReference(procParamType)
                };

                codeMethod.Parameters.Add(paramDecl);

                var            paramVarExpr = new CodeVariableReferenceExpression(paramDecl.Name);
                CodeExpression argExpr      = GetArgumentExpression(paramTypeInfo, procParamType, paramVarExpr);

                methodInvoke.Parameters.Add(argExpr);
            }

            CodeVariableReferenceExpression resultVarExpr = null;

            if (function.ReturnType.ClrType == typeof(void))
            {
                codeMethod.Statements.Add(new CodeExpressionStatement(methodInvoke));
            }
            else
            {
                var resultVarDecl = new CodeVariableDeclarationStatement {
                    Name           = "result",
                    InitExpression = methodInvoke,
                    Type           = new CodeTypeReference(function.Method.ReturnType)
                };

                codeMethod.Statements.Add(resultVarDecl);

                resultVarExpr = new CodeVariableReferenceExpression(resultVarDecl.Name);
            }

            CodeExpression returnExpr = GetReturnExpression(function.ReturnType, resultVarExpr);

            codeMethod.Statements.Add(new CodeMethodReturnStatement(returnExpr));

            return(codeMethod);
        }
Exemplo n.º 7
0
        CodeExpression TransformInput(CodeVariableReferenceExpression argumentsRef, int position, XPathSequenceType sequenceType)
        {
            var codeBuilder = new StringBuilder()
                              .Append(argumentsRef.VariableName)
                              .AppendFormatInvariant("[{0}]", position - 1);

            bool isAtomic = sequenceType.ItemType.Kind == XPathItemKind.Atomic;
            bool isNode   = sequenceType.ItemType.KindIsNode;

            if (isAtomic)
            {
                codeBuilder.Append(".AsAtomicValues()");
            }
            else if (isNode)
            {
                codeBuilder.Append(".AsNodes()");
            }
            else
            {
                codeBuilder.Append(".AsItems()");
            }

            var itemExpr = new StringBuilder("x");

            if (isAtomic)
            {
                itemExpr.Append(".Value");

                QName atomicSchemaType = GetAtomicSchemaType(sequenceType.ItemType);

                Type expectedType = sequenceType.ItemType.ClrType;
                Type actualType   = (atomicSchemaType.Uri == XMLSchemaNamespace) ?
                                    SaxonAtomicMapping(atomicSchemaType.LocalName)
               : typeof(object);

                string expectedTypeName = GetCSharpFullName(expectedType);

                if (expectedType.IsAssignableFrom(actualType))
                {
                    itemExpr.Insert(0, "({0})".FormatInvariant(expectedTypeName));
                }
                else
                {
                    if (actualType == typeof(QName) &&
                        expectedType == typeof(XmlQualifiedName))
                    {
                        itemExpr.Insert(0, "(({0})".FormatInvariant(GetCSharpFullName(actualType)));
                        itemExpr.Append(").ToXmlQualifiedName()");
                    }
                    else
                    {
                        itemExpr.Insert(0, "({0}){1}.ChangeType(".FormatInvariant(expectedTypeName, typeof(Convert).FullName));
                        itemExpr.AppendFormatInvariant(", typeof({0}))", expectedTypeName);
                    }
                }
            }
            else if (isNode)
            {
                itemExpr.Append(".ToXPathNavigator()");
            }
            else
            {
                itemExpr.Append(".ToXPathItem()");
            }

            if (itemExpr.Length > 1)
            {
                codeBuilder.Append(".Select(x => ");
                codeBuilder.Append(itemExpr.ToString());
                codeBuilder.Append(")");
            }

            switch (sequenceType.Cardinality)
            {
            case XPathSequenceCardinality.One:
                codeBuilder.Append(".Single()");
                break;

            case XPathSequenceCardinality.ZeroOrOne:

                if (sequenceType.ClrTypeIsNullableValueType)
                {
                    codeBuilder.Insert(0, typeof(SaxonExtensions).FullName + ".SingleOrNull(");
                    codeBuilder.Append(")");
                }
                else
                {
                    codeBuilder.Append(".SingleOrDefault()");
                }

                break;

            case XPathSequenceCardinality.OneOrMore:
            case XPathSequenceCardinality.ZeroOrMore:

                if (sequenceType.ClrType.IsArray)
                {
                    codeBuilder.Append(".ToArray()");
                }

                break;
            }

            return(new CodeSnippetExpression(codeBuilder.ToString()));
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
0
 internal XPathVariableInfo(string name, XPathSequenceType type)
 {
     this._Name = name;
     this._Type = type;
 }