Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,214 @@
;==++==
;
; Copyright (c) Microsoft Corporation. All rights reserved.
;
;==--==
; NOTE: do not use \", use ' instead
; NOTE: Use # or ; for comments
; These are the managed resources for System.Data.SqlXml.dll. See
; ResourceManager documentation and the ResGen tool.
Xml_UserException={0}
Xml_ErrorFilePosition=An error occurred at {0}({1},{2}).
Xml_InvalidOperation=Operation is not valid due to the current state of the object.
; Copy of Exception_EndOfInnerExceptionStack from mscorlib
Xml_EndOfInnerExceptionStack=--- End of inner exception stack trace ---
; XPath error messages
XPath_UnclosedString=String literal was not closed.
XPath_ScientificNotation=Scientific notation is not allowed.
XPath_UnexpectedToken=Unexpected token '{0}' in the expression.
XPath_NodeTestExpected=Expected a node test, found '{0}'.
XPath_EofExpected=Expected end of the expression, found '{0}'.
XPath_TokenExpected=Expected token '{0}', found '{1}'.
XPath_InvalidAxisInPattern=Only 'child' and 'attribute' axes are allowed in a pattern outside predicates.
XPath_PredicateAfterDot=Abbreviated step '.' cannot be followed by a predicate. Use the full form 'self::node()[predicate]' instead.
XPath_PredicateAfterDotDot=Abbreviated step '..' cannot be followed by a predicate. Use the full form 'parent::node()[predicate]' instead.
XPath_NArgsExpected=Function '{0}()' must have {1} argument(s).
XPath_NOrMArgsExpected=Function '{0}()' must have {1} or {2} argument(s).
XPath_AtLeastNArgsExpected=Function '{0}()' must have at least {1} argument(s).
; NOTE: {2} below is not a typo
XPath_AtMostMArgsExpected=Function '{0}()' must have no more than {2} arguments.
XPath_NodeSetArgumentExpected=Argument {1} of function '{0}()' cannot be converted to a node-set.
XPath_NodeSetExpected=Expression must evaluate to a node-set.
XPath_RtfInPathExpr=To use a result tree fragment in a path expression, first convert it to a node-set using the msxsl:node-set() function.
; Xslt error messages
; NOTE: Do not append '.' to the following message
Xslt_WarningAsError=Warning as Error: {0}
Xslt_InputTooComplex=The stylesheet is too complex.
Xslt_CannotLoadStylesheet=Cannot load the stylesheet object referenced by URI '{0}', because the provided XmlResolver returned an object of type '{1}'. One of Stream, XmlReader, and IXPathNavigable types was expected.
Xslt_WrongStylesheetElement=Stylesheet must start either with an 'xsl:stylesheet' or an 'xsl:transform' element, or with a literal result element that has an 'xsl:version' attribute, where prefix 'xsl' denotes the 'http://www.w3.org/1999/XSL/Transform' namespace.
Xslt_WdXslNamespace=The 'http://www.w3.org/TR/WD-xsl' namespace is no longer supported.
Xslt_NotAtTop='{0}' element children must precede all other children of the '{1}' element.
Xslt_UnexpectedElement='{0}' cannot be a child of the '{1}' element.
Xslt_NullNsAtTopLevel=Top-level element '{0}' may not have a null namespace URI.
Xslt_TextNodesNotAllowed='{0}' element cannot have text node children.
Xslt_NotEmptyContents=The contents of '{0}' must be empty.
Xslt_InvalidAttribute='{0}' is an invalid attribute for the '{1}' element.
Xslt_MissingAttribute=Missing mandatory attribute '{0}'.
Xslt_InvalidAttrValue='{1}' is an invalid value for the '{0}' attribute.
Xslt_BistateAttribute=The value of the '{0}' attribute must be '{1}' or '{2}'.
Xslt_CharAttribute=The value of the '{0}' attribute must be a single character.
Xslt_CircularInclude=Stylesheet '{0}' cannot directly or indirectly include or import itself.
Xslt_SingleRightBraceInAvt=The right curly brace in an attribute value template '{0}' outside an expression must be doubled.
Xslt_VariableCntSel2=The variable or parameter '{0}' cannot have both a 'select' attribute and non-empty content.
Xslt_KeyCntUse='xsl:key' has a 'use' attribute and has non-empty content, or it has empty content and no 'use' attribute.
Xslt_DupTemplateName='{0}' is a duplicate template name.
Xslt_BothMatchNameAbsent='xsl:template' must have either a 'match' attribute or a 'name' attribute, or both.
Xslt_InvalidVariable=The variable or parameter '{0}' is either not defined or it is out of scope.
Xslt_DupGlobalVariable=The variable or parameter '{0}' was duplicated with the same import precedence.
Xslt_DupLocalVariable=The variable or parameter '{0}' was duplicated within the same scope.
Xslt_DupNsAlias=Namespace URI '{0}' is declared to be an alias for multiple different namespace URIs with the same import precedence.
Xslt_EmptyAttrValue=The value of the '{0}' attribute cannot be empty.
Xslt_EmptyNsAlias=The value of the '{0}' attribute cannot be empty. Use '#default' to specify the default namespace.
Xslt_UnknownXsltFunction='{0}()' is an unknown XSLT function.
Xslt_UnsupportedXsltFunction='{0}()' is an unsupported XSLT function.
Xslt_NoAttributeSet=A reference to attribute set '{0}' cannot be resolved. An 'xsl:attribute-set' of this name must be declared at the top level of the stylesheet.
Xslt_UndefinedKey=A reference to key '{0}' cannot be resolved. An 'xsl:key' of this name must be declared at the top level of the stylesheet.
Xslt_CircularAttributeSet=Circular reference in the definition of attribute set '{0}'.
Xslt_InvalidCallTemplate=The named template '{0}' does not exist.
Xslt_InvalidPrefix=Prefix '{0}' is not defined.
Xslt_ScriptXsltNamespace=Script block cannot implement the XSLT namespace.
Xslt_ScriptInvalidLanguage=Scripting language '{0}' is not supported.
Xslt_ScriptMixedLanguages=All script blocks implementing the namespace '{0}' must use the same language.
; NOTE: Do not append '.' to the following message
Xslt_ScriptCompileException=Error occurred while compiling the script: {0}
Xslt_ScriptNotAtTop=Element '{0}' must precede script code.
Xslt_AssemblyNameHref='msxsl:assembly' must have either a 'name' attribute or an 'href' attribute, but not both.
Xslt_ScriptAndExtensionClash=Cannot have both an extension object and a script implementing the same namespace '{0}'.
Xslt_NoDecimalFormat=Decimal format '{0}' is not defined.
Xslt_DecimalFormatSignsNotDistinct=The '{0}' and '{1}' attributes of 'xsl:decimal-format' must have distinct values.
Xslt_DecimalFormatRedefined=The '{0}' attribute of 'xsl:decimal-format' cannot be redefined with a value of '{1}'.
Xslt_UnknownExtensionElement='{0}' is not a recognized extension element.
Xslt_ModeWithoutMatch=An 'xsl:template' element without a 'match' attribute cannot have a 'mode' attribute.
Xslt_ModeListEmpty=List of modes in 'xsl:template' element can't be empty.
Xslt_ModeListDup=List of modes in 'xsl:template' element can't contain duplicates ('{0}').
Xslt_ModeListAll=List of modes in 'xsl:template' element can't contain token '#all' together with any other value.
Xslt_PriorityWithoutMatch=An 'xsl:template' element without a 'match' attribute cannot have a 'priority' attribute.
Xslt_InvalidApplyImports=An 'xsl:apply-imports' element can only occur within an 'xsl:template' element with a 'match' attribute, and cannot occur within an 'xsl:for-each' element.
Xslt_DuplicateWithParam=Value of parameter '{0}' cannot be specified more than once within a single 'xsl:call-template' or 'xsl:apply-templates' element.
Xslt_ReservedNS=Elements and attributes cannot belong to the reserved namespace '{0}'.
Xslt_XmlnsAttr=An attribute with a local name 'xmlns' and a null namespace URI cannot be created.
Xslt_NoWhen=An 'xsl:choose' element must have at least one 'xsl:when' child.
Xslt_WhenAfterOtherwise='xsl:when' must precede the 'xsl:otherwise' element.
Xslt_DupOtherwise=An 'xsl:choose' element can have only one 'xsl:otherwise' child.
Xslt_AttributeRedefinition=Attribute '{0}' of 'xsl:output' cannot be defined more than once with the same import precedence.
Xslt_InvalidMethod='{0}' is not a supported output method. Supported methods are 'xml', 'html', and 'text'.
Xslt_InvalidEncoding='{0}' is not a supported encoding name.
Xslt_InvalidLanguage='{0}' is not a supported language identifier.
Xslt_InvalidCompareOption=String comparison option(s) '{0}' are either invalid or cannot be used together.
Xslt_KeyNotAllowed=The 'key()' function cannot be used in 'use' and 'match' attributes of 'xsl:key' element.
Xslt_VariablesNotAllowed=Variables cannot be used within this expression.
Xslt_CurrentNotAllowed=The 'current()' function cannot be used in a pattern.
Xslt_DocumentFuncProhibited=Execution of the 'document()' function was prohibited. Use the XsltSettings.EnableDocumentFunction property to enable it.
Xslt_ScriptsProhibited=Execution of scripts was prohibited. Use the XsltSettings.EnableScript property to enable it.
Xslt_ItemNull=Extension functions cannot return null values.
Xslt_NodeSetNotNode=Cannot convert a node-set which contains zero nodes or more than one node to a single node.
Xslt_UnsupportedClrType=Extension function parameters or return values which have Clr type '{0}' are not supported.
Xslt_NotYetImplemented='{0}' is not yet implemented.
Xslt_SchemaDeclaration='{0}' declaration is not permitted in non-schema aware processor.
Xslt_SchemaAttribute=Attribute '{0}' is not permitted in basic XSLT processor (http://www.w3.org/TR/xslt20/#dt-basic-xslt-processor).
Xslt_SchemaAttributeValue=Value '{1}' of attribute '{0}' is not permitted in basic XSLT processor (http://www.w3.org/TR/xslt20/#dt-basic-xslt-processor).
Xslt_ElementCntSel=The element '{0}' cannot have both a 'select' attribute and non-empty content.
Xslt_PerformSortCntSel=The element 'xsl:perform-sort' cannot have 'select' attribute any content other than 'xsl:sort' and 'xsl:fallback' instructions.
Xslt_RequiredAndSelect=Mandatory parameter '{0}' must be empty and must not have a 'select' attribute.
Xslt_NoSelectNoContent=Element '{0}' must have either 'select' attribute or non-empty content.
Xslt_NonTemplateTunnel=Stylesheet or function parameter '{0}' cannot have attribute 'tunnel'.
Xslt_RequiredOnFunction=The 'required' attribute must not be specified for parameter '{0}'. Function parameters are always mandatory.
Xslt_ExcludeDefault=Value '#default' is used within the 'exclude-result-prefixes' attribute and the parent element of this attribute has no default namespace.
Xslt_CollationSyntax=The value of an 'default-collation' attribute contains no recognized collation URI.
Xslt_AnalyzeStringDupChild='xsl:analyze-string' cannot have second child with name '{0}'.
Xslt_AnalyzeStringChildOrder=When both 'xsl:matching-string' and 'xsl:non-matching-string' elements are present, 'xsl:matching-string' element must come first.
Xslt_AnalyzeStringEmpty='xsl:analyze-string' must contain either 'xsl:matching-string' or 'xsl:non-matching-string' elements or both.
Xslt_SortStable=Only the first 'xsl:sort' element may have 'stable' attribute.
Xslt_InputTypeAnnotations=It is an error if there is a stylesheet module in the stylesheet that specifies 'input-type-annotations'="strip" and another stylesheet module that specifies 'input-type-annotations'="preserve".
; Collation error messages
Coll_BadOptFormat=Collation option '{0}' is invalid. Options must have the following format: <option-name>=<option-value>.
Coll_Unsupported=The collation '{0}' is not supported.
Coll_UnsupportedLanguage=Collation language '{0}' is not supported.
Coll_UnsupportedOpt=Unsupported option '{0}' in collation.
Coll_UnsupportedOptVal=Collation option '{0}' cannot have the value '{1}'.
Coll_UnsupportedSortOpt=Unsupported sort option '{0}' in collation.
; Qil validation error message
Qil_Validation=QIL Validation Error! '{0}'.
; XmlIl engine error messages
XmlIl_TooManyParameters=Functions may not have more than 65535 parameters.
XmlIl_BadXmlState=An item of type '{0}' cannot be constructed within a node of type '{1}'.
XmlIl_BadXmlStateAttr=Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added.
XmlIl_NmspAfterAttr=Namespace nodes cannot be added to the parent element after an attribute node has already been added.
XmlIl_NmspConflict=Cannot construct namespace declaration xmlns{0}{1}='{2}'. Prefix '{1}' is already mapped to namespace '{3}'.
XmlIl_CantResolveEntity=Cannot query the data source object referenced by URI '{0}', because the provided XmlResolver returned an object of type '{1}'. Only Stream, XmlReader, and IXPathNavigable data source objects are currently supported.
XmlIl_NoDefaultDocument=Query requires a default data source, but no default was supplied to the query engine.
XmlIl_UnknownDocument=Data source '{0}' cannot be located.
XmlIl_UnknownParam=Supplied XsltArgumentList does not contain a parameter with local name '{0}' and namespace '{1}'.
XmlIl_UnknownExtObj=Cannot find a script or an extension object associated with namespace '{0}'.
XmlIl_CantStripNav=White space cannot be stripped from input documents that have already been loaded. Provide the input document as an XmlReader instead.
XmlIl_ExtensionError=An error occurred during a call to extension function '{0}'. See InnerException for a complete description of the error.
XmlIl_TopLevelAttrNmsp=XmlWriter cannot process the sequence returned by the query, because it contains an attribute or namespace node.
XmlIl_NoExtensionMethod=Extension object '{0}' does not contain a matching '{1}' method that has {2} parameter(s).
XmlIl_AmbiguousExtensionMethod=Ambiguous method call. Extension object '{0}' contains multiple '{1}' methods that have {2} parameter(s).
XmlIl_NonPublicExtensionMethod=Method '{1}' of extension object '{0}' cannot be called because it is not public.
XmlIl_GenericExtensionMethod=Method '{1}' of extension object '{0}' cannot be called because it is generic.
XmlIl_ByRefType=Method '{1}' of extension object '{0}' cannot be called because it has one or more ByRef parameters.
XmlIl_DocumentLoadError=An error occurred while loading document '{0}'. See InnerException for a complete description of the error.
; XsltOld errors
Xslt_CompileError=XSLT compile error at {0}({1},{2}). See InnerException for details.
Xslt_CompileError2=XSLT compile error.
Xslt_UnsuppFunction='{0}()' is an unsupported XSLT function.
Xslt_NotFirstImport='xsl:import' instructions must precede all other element children of an 'xsl:stylesheet' element.
Xslt_UnexpectedKeyword='{0}' cannot be a child of the '{1}' element.
Xslt_InvalidContents=The contents of '{0}' are invalid.
Xslt_CantResolve=Cannot resolve the referenced document '{0}'.
Xslt_SingleRightAvt=Right curly brace in the attribute value template '{0}' must be doubled.
Xslt_OpenBracesAvt=The braces are not closed in AVT expression '{0}'.
Xslt_OpenLiteralAvt=The literal in AVT expression is not correctly closed '{0}'.
Xslt_NestedAvt=AVT cannot be nested in AVT '{0}'.
Xslt_EmptyAvtExpr=XPath Expression in AVT cannot be empty: '{0}'.
Xslt_InvalidXPath='{0}' is an invalid XPath expression.
Xslt_InvalidQName='{0}' is an invalid QName.
Xslt_NoStylesheetLoaded=No stylesheet was loaded.
Xslt_TemplateNoAttrib=The 'xsl:template' instruction must have the 'match' and/or 'name' attribute present.
Xslt_DupVarName=Variable or parameter '{0}' was duplicated within the same scope.
Xslt_WrongNumberArgs=XSLT function '{0}()' has the wrong number of arguments.
Xslt_NoNodeSetConversion=Cannot convert the operand to a node-set.
Xslt_NoNavigatorConversion=Cannot convert the operand to 'Result tree fragment'.
Xslt_FunctionFailed=Function '{0}()' has failed.
Xslt_InvalidFormat=Format cannot be empty.
Xslt_InvalidFormat1=Format '{0}' cannot have digit symbol after zero digit symbol before a decimal point.
Xslt_InvalidFormat2=Format '{0}' cannot have zero digit symbol after digit symbol after decimal point.
Xslt_InvalidFormat3=Format '{0}' has two pattern separators.
Xslt_InvalidFormat4=Format '{0}' cannot end with a pattern separator.
Xslt_InvalidFormat5=Format '{0}' cannot have two decimal separators.
Xslt_InvalidFormat8=Format string should have at least one digit or zero digit.
Xslt_ScriptCompileErrors=Script compile errors:\n{0}
Xslt_ScriptInvalidPrefix=Cannot find the script or external object that implements prefix '{0}'.
Xslt_ScriptDub=Namespace '{0}' has a duplicate implementation.
Xslt_ScriptEmpty=The 'msxsl:script' element cannot be empty.
Xslt_DupDecimalFormat=Decimal format '{0}' has a duplicate declaration.
Xslt_CircularReference=Circular reference in the definition of variable '{0}'.
Xslt_InvalidExtensionNamespace=Extension namespace cannot be 'null' or an XSLT namespace URI.
Xslt_InvalidModeAttribute=An 'xsl:template' element without a 'match' attribute cannot have a 'mode' attribute.
Xslt_MultipleRoots=There are multiple root elements in the output XML.
Xslt_ApplyImports=The 'xsl:apply-imports' instruction cannot be included within the content of an 'xsl:for-each' instruction or within an 'xsl:template' instruction without the 'match' attribute.
Xslt_Terminate=Transform terminated: '{0}'.
Xslt_InvalidPattern='{0}' is an invalid XSLT pattern.
; Unused Error messages. We keep them to allow deserialization of XsltException serialised in Eveteret
Xslt_EmptyTagRequired=The tag '{0}' must be empty.
Xslt_WrongNamespace=The wrong namespace was used for XSL. Use 'http://www.w3.org/1999/XSL/Transform'.
Xslt_InvalidFormat6=Format '{0}' has both '*' and '_' which is invalid.
Xslt_InvalidFormat7=Format '{0}' has '{1}' which is invalid.
Xslt_ScriptMixLang=Multiple scripting languages for the same namespace is not supported.
Xslt_ScriptInvalidLang=The scripting language '{0}' is not supported.
Xslt_InvalidExtensionPermitions=Extension object should not have wider permissions than the caller of the AddExtensionObject(). If wider permissions are needed, wrap the extension object.
Xslt_InvalidParamNamespace=Parameter cannot belong to XSLT namespace.
Xslt_DuplicateParametr=Duplicate parameter: '{0}'.
Xslt_VariableCntSel=The '{0}' variable has both a select attribute of '{1}' and non-empty contents.

View File

@@ -0,0 +1,12 @@
//------------------------------------------------------------------------------
// <copyright file="Assembly.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System.Runtime.CompilerServices;
// Hard bind to System.Xml
[assembly: Dependency("System.Xml,", LoadHint.Always)]
[assembly: InternalsVisibleTo("System.Xml, PublicKey=00000000000000000400000000000000")]

View File

@@ -0,0 +1,15 @@
//------------------------------------------------------------------------------
// <copyright file="ISourceLineInfo.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
namespace System.Xml.Xsl {
internal interface ISourceLineInfo {
string Uri { get; }
bool IsNoSource { get; }
Location Start { get; }
Location End { get; }
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,262 @@
//------------------------------------------------------------------------------
// <copyright file="OptimizerPatterns.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Xml.Xsl.Qil;
namespace System.Xml.Xsl.IlGen {
internal enum OptimizerPatternName {
None,
DodReverse, // (Dod $reverse-axis:*)
EqualityIndex, // ILGen will build an equality index when this pattern is recognized
FilterAttributeKind, // (Filter $iter:(Content *) (IsType $iter Attribute))
FilterContentKind, // (Filter $iter:* (IsType $iter $kind:*))
FilterElements, // (Filter $iter:* (And (IsType $iter Element) (NameOf $iter (LiteralQName * * *))))
IsDocOrderDistinct, // True if the annotated expression always returns nodes in document order, with no duplicates
IsPositional, // True if the annotated iterator should track current position during iteration
JoinAndDod, // (Dod (Loop $path1:* $path2:*)), where $path2.ContextNode = $path1
MaxPosition, // True if the position range of the annoted iterator or length expression has a maximum
SameDepth, // True if the annotated expression always returns nodes at the same depth in the tree
Step, // True if the annotated expression returns nodes from one of the simple axis operators, or from a union of Content operators
SingleTextRtf, // (RtfCtor (TextCtor *) *)
Axis, // (AnyAxis *)
MaybeSideEffects, // True if annotated expression might have side effects
TailCall, // (Invoke * *) True if invocation can be compiled as using .tailcall
DodMerge, // (Dod (Loop * (Invoke * *))), where invoked function returns nodes in document order
IsReferenced, // True if the annotated global iterator is referenced at least once
}
internal enum OptimizerPatternArgument {
StepNode = 0, // Step, QilNode: The QilNode of the inner step expression (Content, DescendantOrSelf, XPathFollowing, Union, etc.)
StepInput = 1, // Step, QilNode: The expression from which navigation begins
ElementQName = 2, // FilterElements, QilLiteral: All but elements of this QName are filtered by FilterElements expression
KindTestType = 2, // FilterContentKind, XmlType: All but nodes of this XmlType are filtered by FilterContentKind expression
IndexedNodes = 0, // EqualityIndex, QilNode: Expression that returns the nodes to be indexed
KeyExpression = 1, // EqualityIndex, QilNode: Expression that returns the keys for the index
DodStep = 2, // JoinAndDod | DodReverse, QilNode: Last step in a JoinAndDod expression, or only step in DodReverse expression
MaxPosition = 2, // MaxPosition, int: Maximum position of the annotated iterator or length expression
RtfText = 2, // SingleTextRtf, QilNode: Expression that constructs the text of the simple text Rtf
}
/// <summary>
/// As the Qil graph is traversed, patterns are identified. Subtrees that match these patterns are
/// annotated with this class, which identifies the matching patterns and their arguments.
/// </summary>
internal class OptimizerPatterns : IQilAnnotation {
private static readonly int PatternCount = Enum.GetValues(typeof(OptimizerPatternName)).Length;
private int patterns; // Set of patterns that the annotated Qil node and its subtree matches
private bool isReadOnly; // True if setters are disabled in the case of singleton OptimizerPatterns
private object arg0, arg1, arg2; // Arguments to the matching patterns
private static volatile OptimizerPatterns ZeroOrOneDefault;
private static volatile OptimizerPatterns MaybeManyDefault;
private static volatile OptimizerPatterns DodDefault;
/// <summary>
/// Get OptimizerPatterns annotation for the specified node. Lazily create if necessary.
/// </summary>
public static OptimizerPatterns Read(QilNode nd) {
XmlILAnnotation ann = nd.Annotation as XmlILAnnotation;
OptimizerPatterns optPatt = (ann != null) ? ann.Patterns : null;
if (optPatt == null) {
if (!nd.XmlType.MaybeMany) {
// Expressions with ZeroOrOne cardinality should always report IsDocOrderDistinct and NoContainedNodes
if (ZeroOrOneDefault == null) {
optPatt = new OptimizerPatterns();
optPatt.AddPattern(OptimizerPatternName.IsDocOrderDistinct);
optPatt.AddPattern(OptimizerPatternName.SameDepth);
optPatt.isReadOnly = true;
ZeroOrOneDefault = optPatt;
}
else {
optPatt = ZeroOrOneDefault;
}
}
else if (nd.XmlType.IsDod) {
if (DodDefault == null) {
optPatt = new OptimizerPatterns();
optPatt.AddPattern(OptimizerPatternName.IsDocOrderDistinct);
optPatt.isReadOnly = true;
DodDefault = optPatt;
}
else {
optPatt = DodDefault;
}
}
else {
if (MaybeManyDefault == null) {
optPatt = new OptimizerPatterns();
optPatt.isReadOnly = true;
MaybeManyDefault = optPatt;
}
else {
optPatt = MaybeManyDefault;
}
}
}
return optPatt;
}
/// <summary>
/// Create and initialize OptimizerPatterns annotation for the specified node.
/// </summary>
public static OptimizerPatterns Write(QilNode nd) {
XmlILAnnotation ann = XmlILAnnotation.Write(nd);
OptimizerPatterns optPatt = ann.Patterns;
if (optPatt == null || optPatt.isReadOnly) {
optPatt = new OptimizerPatterns();
ann.Patterns = optPatt;
if (!nd.XmlType.MaybeMany) {
optPatt.AddPattern(OptimizerPatternName.IsDocOrderDistinct);
optPatt.AddPattern(OptimizerPatternName.SameDepth);
}
else if (nd.XmlType.IsDod) {
optPatt.AddPattern(OptimizerPatternName.IsDocOrderDistinct);
}
}
return optPatt;
}
/// <summary>
/// Create and initialize OptimizerPatterns annotation for the specified node.
/// </summary>
public static void Inherit(QilNode ndSrc, QilNode ndDst, OptimizerPatternName pattern) {
OptimizerPatterns annSrc = OptimizerPatterns.Read(ndSrc);
if (annSrc.MatchesPattern(pattern)) {
OptimizerPatterns annDst = OptimizerPatterns.Write(ndDst);
annDst.AddPattern(pattern);
// Inherit pattern arguments
switch (pattern) {
case OptimizerPatternName.Step:
annDst.AddArgument(OptimizerPatternArgument.StepNode, annSrc.GetArgument(OptimizerPatternArgument.StepNode));
annDst.AddArgument(OptimizerPatternArgument.StepInput, annSrc.GetArgument(OptimizerPatternArgument.StepInput));
break;
case OptimizerPatternName.FilterElements:
annDst.AddArgument(OptimizerPatternArgument.ElementQName, annSrc.GetArgument(OptimizerPatternArgument.ElementQName));
break;
case OptimizerPatternName.FilterContentKind:
annDst.AddArgument(OptimizerPatternArgument.KindTestType, annSrc.GetArgument(OptimizerPatternArgument.KindTestType));
break;
case OptimizerPatternName.EqualityIndex:
annDst.AddArgument(OptimizerPatternArgument.IndexedNodes, annSrc.GetArgument(OptimizerPatternArgument.IndexedNodes));
annDst.AddArgument(OptimizerPatternArgument.KeyExpression, annSrc.GetArgument(OptimizerPatternArgument.KeyExpression));
break;
case OptimizerPatternName.DodReverse:
case OptimizerPatternName.JoinAndDod:
annDst.AddArgument(OptimizerPatternArgument.DodStep, annSrc.GetArgument(OptimizerPatternArgument.DodStep));
break;
case OptimizerPatternName.MaxPosition:
annDst.AddArgument(OptimizerPatternArgument.MaxPosition, annSrc.GetArgument(OptimizerPatternArgument.MaxPosition));
break;
case OptimizerPatternName.SingleTextRtf:
annDst.AddArgument(OptimizerPatternArgument.RtfText, annSrc.GetArgument(OptimizerPatternArgument.RtfText));
break;
}
}
}
/// <summary>
/// Add an argument to one of the matching patterns.
/// </summary>
public void AddArgument(OptimizerPatternArgument argId, object arg) {
Debug.Assert(!this.isReadOnly, "This OptimizerPatterns instance is read-only.");
switch ((int) argId) {
case 0: this.arg0 = arg; break;
case 1: this.arg1 = arg; break;
case 2: this.arg2 = arg; break;
default:
Debug.Assert(false, "Cannot handle more than 2 arguments.");
break;
}
}
/// <summary>
/// Get an argument of one of the matching patterns.
/// </summary>
public object GetArgument(OptimizerPatternArgument argNum) {
object arg = null;
switch ((int) argNum) {
case 0: arg = this.arg0; break;
case 1: arg = this.arg1; break;
case 2: arg = this.arg2; break;
}
Debug.Assert(arg != null, "There is no '" + argNum + "' argument.");
return arg;
}
/// <summary>
/// Add a pattern to the list of patterns that the annotated node matches.
/// </summary>
public void AddPattern(OptimizerPatternName pattern) {
Debug.Assert(Enum.IsDefined(typeof(OptimizerPatternName), pattern));
Debug.Assert((int) pattern < 32);
Debug.Assert(!this.isReadOnly, "This OptimizerPatterns instance is read-only.");
this.patterns |= (1 << (int) pattern);
}
/// <summary>
/// Return true if the annotated node matches the specified pattern.
/// </summary>
public bool MatchesPattern(OptimizerPatternName pattern) {
Debug.Assert(Enum.IsDefined(typeof(OptimizerPatternName), pattern));
return (this.patterns & (1 << (int) pattern)) != 0;
}
/// <summary>
/// Return name of this annotation.
/// </summary>
public virtual string Name {
get { return "Patterns"; }
}
/// <summary>
/// Return string representation of this annotation.
/// </summary>
public override string ToString() {
string s = "";
for (int pattNum = 0; pattNum < PatternCount; pattNum++) {
if (MatchesPattern((OptimizerPatternName) pattNum)) {
if (s.Length != 0)
s += ", ";
s += ((OptimizerPatternName) pattNum).ToString();
}
}
return s;
}
}
}

View File

@@ -0,0 +1,221 @@
//------------------------------------------------------------------------------
// <copyright file="StaticDataManager.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
// <owner current="false">[....]</owner>
//------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.Runtime;
namespace System.Xml.Xsl.IlGen {
/// <summary>
/// This internal class maintains a list of unique values. Each unique value is assigned a unique ID, which can
/// be used to quickly access the value, since it corresponds to the value's position in the list.
/// </summary>
internal class UniqueList<T> {
private Dictionary<T, int> lookup = new Dictionary<T, int>();
private List<T> list = new List<T>();
/// <summary>
/// If "value" is already in the list, do not add it. Return the unique ID of the value in the list.
/// </summary>
public int Add(T value) {
int id;
if (!this.lookup.ContainsKey(value)) {
// The value does not yet exist, so add it to the list
id = list.Count;
this.lookup.Add(value, id);
this.list.Add(value);
}
else {
id = this.lookup[value];
}
return id;
}
/// <summary>
/// Return an array of the unique values.
/// </summary>
public T[] ToArray() {
return list.ToArray();
}
}
/// <summary>
/// Manages all static data that is used by the runtime. This includes:
/// 1. All NCName and QName atoms that will be used at run-time
/// 2. All QName filters that will be used at run-time
/// 3. All Xml types that will be used at run-time
/// 4. All global variables and parameters
/// </summary>
internal class StaticDataManager {
private UniqueList<string> uniqueNames;
private UniqueList<Int32Pair> uniqueFilters;
private List<StringPair[]> prefixMappingsList;
private List<string> globalNames;
private UniqueList<EarlyBoundInfo> earlyInfo;
private UniqueList<XmlQueryType> uniqueXmlTypes;
private UniqueList<XmlCollation> uniqueCollations;
/// <summary>
/// Add "name" to the list of unique names that are used by this query. Return the index of
/// the unique name in the list.
/// </summary>
public int DeclareName(string name) {
if (this.uniqueNames == null)
this.uniqueNames = new UniqueList<string>();
return this.uniqueNames.Add(name);
}
/// <summary>
/// Return an array of all names that are used by the query (null if no names).
/// </summary>
public string[] Names {
get { return (this.uniqueNames != null) ? this.uniqueNames.ToArray() : null; }
}
/// <summary>
/// Add a name filter to the list of unique filters that are used by this query. Return the index of
/// the unique filter in the list.
/// </summary>
public int DeclareNameFilter(string locName, string nsUri) {
if (this.uniqueFilters == null)
this.uniqueFilters = new UniqueList<Int32Pair>();
return this.uniqueFilters.Add(new Int32Pair(DeclareName(locName), DeclareName(nsUri)));
}
/// <summary>
/// Return an array of all name filters, where each name filter is represented as a pair of integer offsets (localName, namespaceUri)
/// into the Names array (null if no name filters).
/// </summary>
public Int32Pair[] NameFilters {
get { return (this.uniqueFilters != null) ? this.uniqueFilters.ToArray() : null; }
}
/// <summary>
/// Add a list of QilExpression NamespaceDeclarations to an array of strings (prefix followed by namespace URI).
/// Return index of the prefix mappings within this array.
/// </summary>
public int DeclarePrefixMappings(IList<QilNode> list) {
StringPair[] prefixMappings;
// Fill mappings array
prefixMappings = new StringPair[list.Count];
for (int i = 0; i < list.Count; i++) {
// Each entry in mappings array must be a constant NamespaceDeclaration
QilBinary ndNmspDecl = (QilBinary) list[i];
Debug.Assert(ndNmspDecl != null);
Debug.Assert(ndNmspDecl.Left is QilLiteral && ndNmspDecl.Right is QilLiteral);
prefixMappings[i] = new StringPair((string) (QilLiteral) ndNmspDecl.Left, (string) (QilLiteral) ndNmspDecl.Right);
}
// Add mappings to list and return index
if (this.prefixMappingsList == null)
this.prefixMappingsList = new List<StringPair[]>();
this.prefixMappingsList.Add(prefixMappings);
return this.prefixMappingsList.Count - 1;
}
/// <summary>
/// Return an array of all prefix mappings that are used by the query to compute names (null if no mappings).
/// </summary>
public StringPair[][] PrefixMappingsList {
get { return (this.prefixMappingsList != null) ? this.prefixMappingsList.ToArray() : null; }
}
/// <summary>
/// Declare a new global variable or parameter.
/// </summary>
public int DeclareGlobalValue(string name) {
int idx;
if (this.globalNames == null)
this.globalNames = new List<string>();
idx = this.globalNames.Count;
this.globalNames.Add(name);
return idx;
}
/// <summary>
/// Return an array containing the names of all global variables and parameters.
/// </summary>
public string[] GlobalNames {
get { return (this.globalNames != null) ? this.globalNames.ToArray() : null; }
}
/// <summary>
/// Add early bound information to a list that is used by this query. Return the index of
/// the early bound information in the list.
/// </summary>
public int DeclareEarlyBound(string namespaceUri, Type ebType) {
if (this.earlyInfo == null)
this.earlyInfo = new UniqueList<EarlyBoundInfo>();
return this.earlyInfo.Add(new EarlyBoundInfo(namespaceUri, ebType));
}
/// <summary>
/// Return an array of all early bound information that is used by the query (null if none is used).
/// </summary>
public EarlyBoundInfo[] EarlyBound {
get {
if (this.earlyInfo != null)
return this.earlyInfo.ToArray();
return null;
}
}
/// <summary>
/// Add "type" to the list of unique types that are used by this query. Return the index of
/// the unique type in the list.
/// </summary>
public int DeclareXmlType(XmlQueryType type) {
if (this.uniqueXmlTypes == null)
this.uniqueXmlTypes = new UniqueList<XmlQueryType>();
XmlQueryTypeFactory.CheckSerializability(type);
return this.uniqueXmlTypes.Add(type);
}
/// <summary>
/// Return an array of all types that are used by the query (null if no names).
/// </summary>
public XmlQueryType[] XmlTypes {
get { return (this.uniqueXmlTypes != null) ? this.uniqueXmlTypes.ToArray() : null; }
}
/// <summary>
/// Add "collation" to the list of unique collations that are used by this query. Return the index of
/// the unique collation in the list.
/// </summary>
public int DeclareCollation(string collation) {
if (this.uniqueCollations == null)
this.uniqueCollations = new UniqueList<XmlCollation>();
return this.uniqueCollations.Add(XmlCollation.Create(collation));
}
/// <summary>
/// Return an array of all collations that are used by the query (null if no names).
/// </summary>
public XmlCollation[] Collations {
get { return (this.uniqueCollations != null) ? this.uniqueCollations.ToArray() : null; }
}
}
}

View File

@@ -0,0 +1,87 @@
//------------------------------------------------------------------------------
// <copyright file="TailCallAnalyzer.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Xml.Xsl.Qil;
namespace System.Xml.Xsl.IlGen {
/// <summary>
/// This analyzer walks each function in the graph and annotates Invoke nodes which can
/// be compiled using the IL .tailcall instruction. This instruction will discard the
/// current stack frame before calling the new function.
/// </summary>
internal static class TailCallAnalyzer {
/// <summary>
/// Perform tail-call analysis on the functions in the specified QilExpression.
/// </summary>
public static void Analyze(QilExpression qil) {
foreach (QilFunction ndFunc in qil.FunctionList) {
// Only analyze functions which are pushed to the writer, since otherwise code
// is generated after the call instruction in order to process cached results
if (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer)
AnalyzeDefinition(ndFunc.Definition);
}
}
/// <summary>
/// Recursively analyze the definition of a function.
/// </summary>
private static void AnalyzeDefinition(QilNode nd) {
Debug.Assert(XmlILConstructInfo.Read(nd).PushToWriterLast,
"Only need to analyze expressions which will be compiled in push mode.");
switch (nd.NodeType) {
case QilNodeType.Invoke:
// Invoke node can either be compiled as IteratorThenWriter, or Writer.
// Since IteratorThenWriter involves caching the results of the function call
// and iterating over them, .tailcall cannot be used
if (XmlILConstructInfo.Read(nd).ConstructMethod == XmlILConstructMethod.Writer)
OptimizerPatterns.Write(nd).AddPattern(OptimizerPatternName.TailCall);
break;
case QilNodeType.Loop: {
// Recursively analyze Loop return value
QilLoop ndLoop = (QilLoop) nd;
if (ndLoop.Variable.NodeType == QilNodeType.Let || !ndLoop.Variable.Binding.XmlType.MaybeMany)
AnalyzeDefinition(ndLoop.Body);
break;
}
case QilNodeType.Sequence: {
// Recursively analyze last expression in Sequence
QilList ndSeq = (QilList) nd;
if (ndSeq.Count > 0)
AnalyzeDefinition(ndSeq[ndSeq.Count - 1]);
break;
}
case QilNodeType.Choice: {
// Recursively analyze Choice branches
QilChoice ndChoice = (QilChoice) nd;
for (int i = 0; i < ndChoice.Branches.Count; i++)
AnalyzeDefinition(ndChoice.Branches[i]);
break;
}
case QilNodeType.Conditional: {
// Recursively analyze Conditional branches
QilTernary ndCond = (QilTernary) nd;
AnalyzeDefinition(ndCond.Center);
AnalyzeDefinition(ndCond.Right);
break;
}
case QilNodeType.Nop:
AnalyzeDefinition(((QilUnary) nd).Child);
break;
}
}
}
}

View File

@@ -0,0 +1,134 @@
//------------------------------------------------------------------------------
// <copyright file="XmlILAnnotation.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
using System.Xml.Xsl.Qil;
namespace System.Xml.Xsl.IlGen {
/// <summary>
/// Several annotations are created and attached to Qil nodes during the optimization and code generation phase.
/// </summary>
internal class XmlILAnnotation : ListBase<object> {
private object annPrev;
private MethodInfo funcMethod;
private int argPos;
private IteratorDescriptor iterInfo;
private XmlILConstructInfo constrInfo;
private OptimizerPatterns optPatt;
//-----------------------------------------------
// Constructor
//-----------------------------------------------
/// <summary>
/// Create and initialize XmlILAnnotation for the specified node.
/// </summary>
public static XmlILAnnotation Write(QilNode nd) {
XmlILAnnotation ann = nd.Annotation as XmlILAnnotation;
if (ann == null) {
ann = new XmlILAnnotation(nd.Annotation);
nd.Annotation = ann;
}
return ann;
}
private XmlILAnnotation(object annPrev) {
this.annPrev = annPrev;
}
//-----------------------------------------------
// Annotations
//-----------------------------------------------
/// <summary>
/// User-defined functions and global variables and parameters are bound to Clr MethodInfo objects.
/// Attached to Function, global Let, and global Parameter nodes.
/// </summary>
public MethodInfo FunctionBinding {
get { return this.funcMethod; }
set { this.funcMethod = value; }
}
/// <summary>
/// Function arguments are tracked by position.
/// Attached to function Parameter nodes.
/// </summary>
public int ArgumentPosition {
get { return this.argPos; }
set { this.argPos = value; }
}
/// <summary>
/// The IteratorDescriptor that is derived for Qil For and Let nodes is cached so that it can be used when the
/// For/Let node is referenced.
/// Attached to For and Let nodes.
/// </summary>
public IteratorDescriptor CachedIteratorDescriptor {
get { return this.iterInfo; }
set { this.iterInfo = value; }
}
/// <summary>
/// Contains information about how this expression will be constructed by ILGen.
/// Attached to any kind of Qil node.
/// </summary>
public XmlILConstructInfo ConstructInfo {
get { return this.constrInfo; }
set { this.constrInfo = value; }
}
/// <summary>
/// Contains patterns that the subtree rooted at this node matches.
/// Attached to any kind of Qil node.
/// </summary>
public OptimizerPatterns Patterns {
get { return this.optPatt; }
set { this.optPatt = value; }
}
//-----------------------------------------------
// ListBase implementation
//-----------------------------------------------
/// <summary>
/// Return the count of sub-annotations maintained by this annotation.
/// </summary>
public override int Count {
get { return (this.annPrev != null) ? 3 : 2; }
}
/// <summary>
/// Return the annotation at the specified index.
/// </summary>
public override object this[int index] {
get {
if (this.annPrev != null) {
if (index == 0)
return this.annPrev;
index--;
}
switch (index) {
case 0: return this.constrInfo;
case 1: return this.optPatt;
}
throw new IndexOutOfRangeException();
}
set {
throw new NotSupportedException();
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,347 @@
//------------------------------------------------------------------------------
// <copyright file="XmlILModule.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
// <owner current="false">[....]</owner>
//------------------------------------------------------------------------------
using System.Collections;
using System.Diagnostics;
using System.Diagnostics.SymbolStore;
using System.Reflection;
using System.Reflection.Emit;
using System.Security;
using System.Security.Permissions;
using System.Xml.Xsl.Runtime;
using System.Runtime.Versioning;
namespace System.Xml.Xsl.IlGen {
using DebuggingModes = DebuggableAttribute.DebuggingModes;
internal enum XmlILMethodAttributes {
None = 0,
NonUser = 1, // Non-user method which should debugger should step through
Raw = 2, // Raw method which should not add an implicit first argument of type XmlQueryRuntime
}
internal class XmlILModule {
public static readonly PermissionSet CreateModulePermissionSet; // Permission set that contains permissions required for generating module
private static long AssemblyId; // Unique identifier used to ensure that assembly names are unique within AppDomain
private static ModuleBuilder LREModule; // Module used to emit dynamic lightweight-reflection-emit (LRE) methods
private TypeBuilder typeBldr;
private Hashtable methods, urlToSymWriter;
private string modFile;
private bool persistAsm, useLRE, emitSymbols;
private static readonly Guid LanguageGuid = new Guid(0x462d4a3e, 0xb257, 0x4aee, 0x97, 0xcd, 0x59, 0x18, 0xc7, 0x53, 0x17, 0x58);
private static readonly Guid VendorGuid = new Guid(0x994b45c4, 0xe6e9, 0x11d2, 0x90, 0x3f, 0x00, 0xc0, 0x4f, 0xa3, 0x02, 0xa1);
private const string RuntimeName = "{" + XmlReservedNs.NsXslDebug + "}" + "runtime";
static XmlILModule() {
AssemblyName asmName;
AssemblyBuilder asmBldr;
CreateModulePermissionSet = new PermissionSet(PermissionState.None);
// CreateDelegate demands MemberAccess permission
CreateModulePermissionSet.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
// DynamicMethod constructor demands ControlEvidence permissions.
// Emitting symbols in DefineDynamicModule (to allow to debug the stylesheet) requires UnmanagedCode permission.
CreateModulePermissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.UnmanagedCode));
AssemblyId = 0;
// 1. LRE assembly only needs to execute
// 2. No temp files need be created
// 3. Never allow assembly to Assert permissions
asmName = CreateAssemblyName();
asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
try {
CreateModulePermissionSet.Assert();
// Add custom attribute to assembly marking it as security transparent so that Assert will not be allowed
// and link demands will be converted to full demands.
asmBldr.SetCustomAttribute(new CustomAttributeBuilder(XmlILConstructors.Transparent, new object[] {}));
// Store LREModule once. If multiple threads are doing this, then some threads might get different
// modules. This is OK, since it's not mandatory to share, just preferable.
LREModule = asmBldr.DefineDynamicModule("System.Xml.Xsl.CompiledQuery", false);
}
finally {
CodeAccessPermission.RevertAssert();
}
}
public XmlILModule(TypeBuilder typeBldr) {
this.typeBldr = typeBldr;
this.emitSymbols = ((ModuleBuilder) this.typeBldr.Module).GetSymWriter() != null;
this.useLRE = false;
this.persistAsm = false;
// Index all methods added to this module by unique name
this.methods = new Hashtable();
if (this.emitSymbols) {
// Create mapping from source document to symbol writer
this.urlToSymWriter = new Hashtable();
}
}
public bool EmitSymbols {
get {
return this.emitSymbols;
}
}
// SxS note: AssemblyBuilder.DefineDynamicModule() below may be using name which is not SxS safe.
// This file is written only for internal tracing/debugging purposes. In retail builds persistAsm
// will be always false and the file should never be written. As a result it's fine just to supress
// the the SxS warning.
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
[ResourceExposure(ResourceScope.None)]
public XmlILModule(bool useLRE, bool emitSymbols) {
AssemblyName asmName;
AssemblyBuilder asmBldr;
ModuleBuilder modBldr;
Debug.Assert(!(useLRE && emitSymbols));
this.useLRE = useLRE;
this.emitSymbols = emitSymbols;
this.persistAsm = false;
// Index all methods added to this module by unique name
this.methods = new Hashtable();
if (!useLRE) {
// 1. If assembly needs to support debugging, then it must be saved and re-loaded (rule of CLR)
// 2. Get path of temp directory, where assembly will be saved
// 3. Never allow assembly to Assert permissions
asmName = CreateAssemblyName();
#if DEBUG
if (XmlILTrace.IsEnabled) {
this.modFile = "System.Xml.Xsl.CompiledQuery";
this.persistAsm = true;
}
#endif
asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(
asmName,
this.persistAsm ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
// Add custom attribute to assembly marking it as security transparent so that Assert will not be allowed
// and link demands will be converted to full demands.
asmBldr.SetCustomAttribute(new CustomAttributeBuilder(XmlILConstructors.Transparent, new object[] { }));
if (emitSymbols) {
// Create mapping from source document to symbol writer
this.urlToSymWriter = new Hashtable();
// Add DebuggableAttribute to assembly so that debugging is a better experience
DebuggingModes debuggingModes = DebuggingModes.Default | DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggingModes.DisableOptimizations;
asmBldr.SetCustomAttribute(new CustomAttributeBuilder(XmlILConstructors.Debuggable, new object[] {debuggingModes}));
}
// Create ModuleBuilder
if (this.persistAsm)
modBldr = asmBldr.DefineDynamicModule("System.Xml.Xsl.CompiledQuery", this.modFile + ".dll", emitSymbols);
else
modBldr = asmBldr.DefineDynamicModule("System.Xml.Xsl.CompiledQuery", emitSymbols);
this.typeBldr = modBldr.DefineType("System.Xml.Xsl.CompiledQuery.Query", TypeAttributes.Public);
}
}
/// <summary>
/// Define a method in this module with the specified name and parameters.
/// </summary>
public MethodInfo DefineMethod(string name, Type returnType, Type[] paramTypes, string[] paramNames, XmlILMethodAttributes xmlAttrs) {
MethodInfo methResult;
int uniqueId = 1;
string nameOrig = name;
Type[] paramTypesNew;
bool isRaw = (xmlAttrs & XmlILMethodAttributes.Raw) != 0;
// Ensure that name is unique
while (this.methods[name] != null) {
// Add unique id to end of name in order to make it unique within this module
uniqueId++;
name = nameOrig + " (" + uniqueId + ")";
}
if (!isRaw) {
// XmlQueryRuntime is always 0th parameter
paramTypesNew = new Type[paramTypes.Length + 1];
paramTypesNew[0] = typeof(XmlQueryRuntime);
Array.Copy(paramTypes, 0, paramTypesNew, 1, paramTypes.Length);
paramTypes = paramTypesNew;
}
if (!this.useLRE) {
MethodBuilder methBldr;
methBldr = this.typeBldr.DefineMethod(
name,
MethodAttributes.Private | MethodAttributes.Static,
returnType,
paramTypes);
if (emitSymbols && (xmlAttrs & XmlILMethodAttributes.NonUser) != 0) {
// Add DebuggerStepThroughAttribute and DebuggerNonUserCodeAttribute to non-user methods so that debugging is a better experience
methBldr.SetCustomAttribute(new CustomAttributeBuilder(XmlILConstructors.StepThrough, new object[] {}));
methBldr.SetCustomAttribute(new CustomAttributeBuilder(XmlILConstructors.NonUserCode, new object[] {}));
}
if (!isRaw)
methBldr.DefineParameter(1, ParameterAttributes.None, RuntimeName);
for (int i = 0; i < paramNames.Length; i++) {
if (paramNames[i] != null && paramNames[i].Length != 0)
methBldr.DefineParameter(i + (isRaw ? 1 : 2), ParameterAttributes.None, paramNames[i]);
}
methResult = methBldr;
}
else {
DynamicMethod methDyn = new DynamicMethod(name, returnType, paramTypes, LREModule);
methDyn.InitLocals = true;
if (!isRaw)
methDyn.DefineParameter(1, ParameterAttributes.None, RuntimeName);
for (int i = 0; i < paramNames.Length; i++) {
if (paramNames[i] != null && paramNames[i].Length != 0)
methDyn.DefineParameter(i + (isRaw ? 1 : 2), ParameterAttributes.None, paramNames[i]);
}
methResult = methDyn;
}
// Index method by name
this.methods[name] = methResult;
return methResult;
}
/// <summary>
/// Get an XmlILGenerator that can be used to generate the body of the specified method.
/// </summary>
public static ILGenerator DefineMethodBody(MethodBase methInfo) {
DynamicMethod methDyn = methInfo as DynamicMethod;
if (methDyn != null)
return methDyn.GetILGenerator();
MethodBuilder methBldr = methInfo as MethodBuilder;
if (methBldr != null)
return methBldr.GetILGenerator();
return ((ConstructorBuilder) methInfo).GetILGenerator();
}
/// <summary>
/// Find a MethodInfo of the specified name and return it. Return null if no such method exists.
/// </summary>
public MethodInfo FindMethod(string name) {
return (MethodInfo) this.methods[name];
}
/// <summary>
/// Define ginitialized data field with the specified name and value.
/// </summary>
public FieldInfo DefineInitializedData(string name, byte[] data) {
Debug.Assert(!this.useLRE, "Cannot create initialized data for an LRE module");
return this.typeBldr.DefineInitializedData(name, data, FieldAttributes.Private | FieldAttributes.Static);
}
/// <summary>
/// Define private static field with the specified name and value.
/// </summary>
public FieldInfo DefineField(string fieldName, Type type) {
Debug.Assert(!this.useLRE, "Cannot create field for an LRE module");
return this.typeBldr.DefineField(fieldName, type, FieldAttributes.Private | FieldAttributes.Static);
}
/// <summary>
/// Define static constructor for this type.
/// </summary>
public ConstructorInfo DefineTypeInitializer() {
Debug.Assert(!this.useLRE, "Cannot create type initializer for an LRE module");
return this.typeBldr.DefineTypeInitializer();
}
/// <summary>
/// Add the file name of a document containing source code for this module and return a symbol writer.
/// </summary>
public ISymbolDocumentWriter AddSourceDocument(string fileName) {
ISymbolDocumentWriter symDoc;
Debug.Assert(this.emitSymbols, "Cannot add source information to a module that doesn't allow symbols.");
symDoc = this.urlToSymWriter[fileName] as ISymbolDocumentWriter;
if (symDoc == null) {
symDoc = ((ModuleBuilder) this.typeBldr.Module).DefineDocument(fileName, LanguageGuid, VendorGuid, Guid.Empty);
this.urlToSymWriter.Add(fileName, symDoc);
}
return symDoc;
}
/// <summary>
/// Once all methods have been defined, CreateModule must be called in order to "bake" the methods within
/// this module.
/// </summary>
// SxS note: AssemblyBuilder.Save() below is using name which is not SxS safe. This file is written only for
// internal tracing/debugging purposes. In retail builds persistAsm will be always false and the file should
// never be written. As a result it's fine just to supress the the SxS warning.
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
[ResourceExposure(ResourceScope.None)]
public void BakeMethods() {
Type typBaked;
Hashtable methodsBaked;
if (!this.useLRE) {
typBaked = this.typeBldr.CreateType();
if (this.persistAsm) {
// Persist the assembly to disk
((AssemblyBuilder) this.typeBldr.Module.Assembly).Save(this.modFile + ".dll");
}
// Replace all MethodInfos in this.methods
methodsBaked = new Hashtable(this.methods.Count);
foreach (string methName in this.methods.Keys) {
methodsBaked[methName] = typBaked.GetMethod(methName, BindingFlags.NonPublic | BindingFlags.Static);
}
this.methods = methodsBaked;
// Release TypeBuilder and symbol writer resources
this.typeBldr = null;
this.urlToSymWriter = null;
}
}
/// <summary>
/// Wrap a delegate around a MethodInfo of the specified name and type and return it.
/// </summary>
public Delegate CreateDelegate(string name, Type typDelegate) {
if (!this.useLRE)
return Delegate.CreateDelegate(typDelegate, (MethodInfo) this.methods[name]);
return ((DynamicMethod) this.methods[name]).CreateDelegate(typDelegate);
}
/// <summary>
/// Define unique assembly name (within AppDomain).
/// </summary>
private static AssemblyName CreateAssemblyName() {
AssemblyName name;
System.Threading.Interlocked.Increment(ref AssemblyId);
name = new AssemblyName();
name.Name = "System.Xml.Xsl.CompiledQuery." + AssemblyId;
return name;
}
}
}

View File

@@ -0,0 +1,164 @@
//------------------------------------------------------------------------------
// <copyright file="XmlILOptimization.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
namespace System.Xml.Xsl.IlGen {
/// <summary>
/// Xml IL patterns.
/// </summary>
internal enum XmlILOptimization {
None,
EliminateLiteralVariables,
TailCall,
// Do not edit this region
// It is auto-generated
#region AUTOGENERATED
AnnotateAncestor,
AnnotateAncestorSelf,
AnnotateAttribute,
AnnotateAttrNmspLoop,
AnnotateBarrier,
AnnotateConstruction,
AnnotateContent,
AnnotateContentLoop,
AnnotateDescendant,
AnnotateDescendantLoop,
AnnotateDescendantSelf,
AnnotateDifference,
AnnotateDod,
AnnotateDodMerge,
AnnotateDodReverse,
AnnotateFilter,
AnnotateFilterAttributeKind,
AnnotateFilterContentKind,
AnnotateFilterElements,
AnnotateFollowingSibling,
AnnotateIndex1,
AnnotateIndex2,
AnnotateIntersect,
AnnotateInvoke,
AnnotateJoinAndDod,
AnnotateLet,
AnnotateMaxLengthEq,
AnnotateMaxLengthGe,
AnnotateMaxLengthGt,
AnnotateMaxLengthLe,
AnnotateMaxLengthLt,
AnnotateMaxLengthNe,
AnnotateMaxPositionEq,
AnnotateMaxPositionLe,
AnnotateMaxPositionLt,
AnnotateNamespace,
AnnotateNodeRange,
AnnotateParent,
AnnotatePositionalIterator,
AnnotatePreceding,
AnnotatePrecedingSibling,
AnnotateRoot,
AnnotateRootLoop,
AnnotateSingleTextRtf,
AnnotateSingletonLoop,
AnnotateTrackCallers,
AnnotateUnion,
AnnotateUnionContent,
AnnotateXPathFollowing,
AnnotateXPathPreceding,
CommuteDodFilter,
CommuteFilterLoop,
EliminateAdd,
EliminateAfter,
EliminateAnd,
EliminateAverage,
EliminateBefore,
EliminateConditional,
EliminateDifference,
EliminateDivide,
EliminateDod,
EliminateEq,
EliminateFilter,
EliminateGe,
EliminateGt,
EliminateIntersection,
EliminateIs,
EliminateIsEmpty,
EliminateIsType,
EliminateIterator,
EliminateIteratorUsedAtMostOnce,
EliminateLe,
EliminateLength,
EliminateLoop,
EliminateLt,
EliminateMaximum,
EliminateMinimum,
EliminateModulo,
EliminateMultiply,
EliminateNamespaceDecl,
EliminateNe,
EliminateNegate,
EliminateNop,
EliminateNot,
EliminateOr,
EliminatePositionOf,
EliminateReturnDod,
EliminateSequence,
EliminateSort,
EliminateStrConcat,
EliminateStrConcatSingle,
EliminateStrLength,
EliminateSubtract,
EliminateSum,
EliminateTypeAssert,
EliminateTypeAssertOptional,
EliminateUnion,
EliminateUnusedGlobals,
EliminateXsltConvert,
FoldConditionalNot,
FoldNamedDescendants,
FoldNone,
FoldXsltConvertLiteral,
IntroduceDod,
IntroducePrecedingDod,
NormalizeAddEq,
NormalizeAddLiteral,
NormalizeAttribute,
NormalizeConditionalText,
NormalizeDifference,
NormalizeEqLiteral,
NormalizeGeLiteral,
NormalizeGtLiteral,
NormalizeIdEq,
NormalizeIdNe,
NormalizeIntersect,
NormalizeInvokeEmpty,
NormalizeLeLiteral,
NormalizeLengthGt,
NormalizeLengthNe,
NormalizeLoopConditional,
NormalizeLoopInvariant,
NormalizeLoopLoop,
NormalizeLoopText,
NormalizeLtLiteral,
NormalizeMuenchian,
NormalizeMultiplyLiteral,
NormalizeNeLiteral,
NormalizeNestedSequences,
NormalizeSingletonLet,
NormalizeSortXsltConvert,
NormalizeUnion,
NormalizeXsltConvertEq,
NormalizeXsltConvertGe,
NormalizeXsltConvertGt,
NormalizeXsltConvertLe,
NormalizeXsltConvertLt,
NormalizeXsltConvertNe,
#endregion // AUTOGENERATED
// Must appear last in the enum
Last_,
}
}

View File

@@ -0,0 +1 @@
e1c869221fa43552e2ba4aeda158583a553d307c

View File

@@ -0,0 +1,195 @@
//------------------------------------------------------------------------------
// <copyright file="XmlILTrace.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.IO;
using System.Security;
using System.Xml;
using System.Globalization;
using System.Xml.Xsl.Qil;
using System.Runtime.Versioning;
// This class is only for debug purposes so there is no need to have it in Retail builds
#if DEBUG
namespace System.Xml.Xsl.IlGen {
/// <summary>
/// Helper class that facilitates tracing of ILGen.
/// </summary>
internal static class XmlILTrace {
private const int MAX_REWRITES = 200;
/// <summary>
/// Check environment variable in order to determine whether to write out trace files. This really should be a
/// check of the configuration file, but System.Xml does not yet have a good tracing story.
/// </summary>
private static volatile string dirName = null;
private static volatile bool alreadyCheckedEnabled = false;
/// <summary>
/// True if tracing has been enabled (environment variable set).
/// </summary>
public static bool IsEnabled {
// SxS: This property poses potential SxS issue. However the class is used only in debug builds (it won't
// get compiled into ret build) so it's OK to suppress the SxS warning.
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
[ResourceExposure(ResourceScope.None)]
get {
// If environment variable has not yet been checked, do so now
if (!alreadyCheckedEnabled) {
try {
dirName = Environment.GetEnvironmentVariable("XmlILTrace");
}
catch (SecurityException) {
// If user does not have access to environment variables, tracing will remain disabled
}
alreadyCheckedEnabled = true;
}
return (dirName != null);
}
}
/// <summary>
/// If tracing is enabled, this method will delete the contents of "filename" in preparation for append
/// operations.
/// </summary>
[ResourceConsumption(ResourceScope.Machine)]
[ResourceExposure(ResourceScope.Machine)]
public static void PrepareTraceWriter(string fileName) {
if (!IsEnabled)
return;
File.Delete(dirName + "\\" + fileName);
}
/// <summary>
/// If tracing is enabled, this method will open a TextWriter over "fileName" and return it. Otherwise,
/// null will be returned.
/// </summary>
[ResourceConsumption(ResourceScope.Machine)]
[ResourceExposure(ResourceScope.Machine)]
public static TextWriter GetTraceWriter(string fileName) {
if (!IsEnabled)
return null;
return new StreamWriter(dirName + "\\" + fileName, true);
}
/// <summary>
/// Serialize Qil tree to "fileName", in the directory identified by "dirName".
/// </summary>
[ResourceConsumption(ResourceScope.Machine)]
[ResourceExposure(ResourceScope.Machine)]
public static void WriteQil(QilExpression qil, string fileName) {
if (!IsEnabled)
return;
XmlWriter w = XmlWriter.Create(dirName + "\\" + fileName);
try {
WriteQil(qil, w);
}
finally {
w.Close();
}
}
/// <summary>
/// Trace ILGen optimizations and log them to "fileName".
/// </summary>
[ResourceConsumption(ResourceScope.Machine)]
[ResourceExposure(ResourceScope.Machine)]
public static void TraceOptimizations(QilExpression qil, string fileName) {
if (!IsEnabled)
return;
XmlWriter w = XmlWriter.Create(dirName + "\\" + fileName);
w.WriteStartDocument();
w.WriteProcessingInstruction("xml-stylesheet", "href='qilo.xslt' type='text/xsl'");
w.WriteStartElement("QilOptimizer");
w.WriteAttributeString("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture));
WriteQilRewrite(qil, w, null);
try {
// Then, rewrite the graph until "done" or some max value is reached.
for (int i = 1; i < MAX_REWRITES; i++) {
QilExpression qilTemp = (QilExpression) (new QilCloneVisitor(qil.Factory).Clone(qil));
XmlILOptimizerVisitor visitor = new XmlILOptimizerVisitor(qilTemp, !qilTemp.IsDebug);
visitor.Threshold = i;
qilTemp = visitor.Optimize();
// In debug code, ensure that QIL after N steps is correct
QilValidationVisitor.Validate(qilTemp);
// Trace the rewrite
WriteQilRewrite(qilTemp, w, OptimizationToString(visitor.LastReplacement));
if (visitor.ReplacementCount < i)
break;
}
}
catch (Exception e) {
if (!XmlException.IsCatchableException(e)) {
throw;
}
w.WriteElementString("Exception", null, e.ToString());
throw;
}
finally {
w.WriteEndElement();
w.WriteEndDocument();
w.Flush();
w.Close();
}
}
/// <summary>
/// Serialize Qil tree to writer "w".
/// </summary>
private static void WriteQil(QilExpression qil, XmlWriter w) {
QilXmlWriter qw = new QilXmlWriter(w);
qw.ToXml(qil);
}
/// <summary>
/// Serialize rewritten Qil tree to writer "w".
/// </summary>
private static void WriteQilRewrite(QilExpression qil, XmlWriter w, string rewriteName) {
w.WriteStartElement("Diff");
if (rewriteName != null)
w.WriteAttributeString("rewrite", rewriteName);
WriteQil(qil, w);
w.WriteEndElement();
}
/// <summary>
/// Get friendly string description of an ILGen optimization.
/// </summary>
private static string OptimizationToString(int opt) {
string s = Enum.GetName(typeof(XmlILOptimization), opt);
if (s.StartsWith("Introduce", StringComparison.Ordinal)) {
return s.Substring(9) + " introduction";
}
else if (s.StartsWith("Eliminate", StringComparison.Ordinal)) {
return s.Substring(9) + " elimination";
}
else if (s.StartsWith("Commute", StringComparison.Ordinal)) {
return s.Substring(7) + " commutation";
}
else if (s.StartsWith("Fold", StringComparison.Ordinal)) {
return s.Substring(4) + " folding";
}
else if (s.StartsWith("Misc", StringComparison.Ordinal)) {
return s.Substring(4);
}
return s;
}
}
}
#endif

View File

@@ -0,0 +1,168 @@
//------------------------------------------------------------------------------
// <copyright file="XmlIlTypeHelper.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Schema;
using System.Xml.Xsl.Runtime;
namespace System.Xml.Xsl.IlGen {
/// <summary>
/// Static QilExpression type helper methods.
/// </summary>
internal class XmlILTypeHelper {
// Not creatable
private XmlILTypeHelper() {
}
/// <summary>
/// Return the default Clr data type that will be used to store instances of the QilNode's type.
/// </summary>
public static Type GetStorageType(XmlQueryType qyTyp) {
Type storageType;
if (qyTyp.IsSingleton) {
storageType = TypeCodeToStorage[(int) qyTyp.TypeCode];
// Non-strict items must store the type along with the value, so use XPathItem
if (!qyTyp.IsStrict && storageType != typeof(XPathNavigator))
return typeof(XPathItem);
}
else {
storageType = TypeCodeToCachedStorage[(int) qyTyp.TypeCode];
// Non-strict items must store the type along with the value, so use XPathItem
if (!qyTyp.IsStrict && storageType != typeof(IList<XPathNavigator>))
return typeof(IList<XPathItem>);
}
return storageType;
}
private static readonly Type[] TypeCodeToStorage = {
typeof(XPathItem), // XmlTypeCode.None
typeof(XPathItem), // XmlTypeCode.Item
typeof(XPathNavigator), // XmlTypeCode.Node
typeof(XPathNavigator), // XmlTypeCode.Document
typeof(XPathNavigator), // XmlTypeCode.Element
typeof(XPathNavigator), // XmlTypeCode.Attribute
typeof(XPathNavigator), // XmlTypeCode.Namespace
typeof(XPathNavigator), // XmlTypeCode.ProcessingInstruction
typeof(XPathNavigator), // XmlTypeCode.Comment
typeof(XPathNavigator), // XmlTypeCode.Text
typeof(XPathItem), // XmlTypeCode.AnyAtomicType
typeof(string), // XmlTypeCode.UntypedAtomic
typeof(string), // XmlTypeCode.String
typeof(bool), // XmlTypeCode.Boolean
typeof(decimal), // XmlTypeCode.Decimal
typeof(float), // XmlTypeCode.Float
typeof(double), // XmlTypeCode.Double
typeof(string), // XmlTypeCode.Duration
typeof(DateTime), // XmlTypeCode.DateTime
typeof(DateTime), // XmlTypeCode.Time
typeof(DateTime), // XmlTypeCode.Date
typeof(DateTime), // XmlTypeCode.GYearMonth
typeof(DateTime), // XmlTypeCode.GYear
typeof(DateTime), // XmlTypeCode.GMonthDay
typeof(DateTime), // XmlTypeCode.GDay
typeof(DateTime), // XmlTypeCode.GMonth
typeof(byte[]), // XmlTypeCode.HexBinary
typeof(byte[]), // XmlTypeCode.Base64Binary
typeof(string), // XmlTypeCode.AnyUri
typeof(XmlQualifiedName), // XmlTypeCode.QName
typeof(XmlQualifiedName), // XmlTypeCode.Notation
typeof(string), // XmlTypeCode.NormalizedString
typeof(string), // XmlTypeCode.Token
typeof(string), // XmlTypeCode.Language
typeof(string), // XmlTypeCode.NmToken
typeof(string), // XmlTypeCode.Name
typeof(string), // XmlTypeCode.NCName
typeof(string), // XmlTypeCode.Id
typeof(string), // XmlTypeCode.Idref
typeof(string), // XmlTypeCode.Entity
typeof(long), // XmlTypeCode.Integer
typeof(decimal), // XmlTypeCode.NonPositiveInteger
typeof(decimal), // XmlTypeCode.NegativeInteger
typeof(long), // XmlTypeCode.Long
typeof(int), // XmlTypeCode.Int
typeof(int), // XmlTypeCode.Short
typeof(int), // XmlTypeCode.Byte
typeof(decimal), // XmlTypeCode.NonNegativeInteger
typeof(decimal), // XmlTypeCode.UnsignedLong
typeof(long), // XmlTypeCode.UnsignedInt
typeof(int), // XmlTypeCode.UnsignedShort
typeof(int), // XmlTypeCode.UnsignedByte
typeof(decimal), // XmlTypeCode.PositiveInteger
typeof(TimeSpan), // XmlTypeCode.YearMonthDuration
typeof(TimeSpan), // XmlTypeCode.DayTimeDuration
};
private static readonly Type[] TypeCodeToCachedStorage = {
typeof(IList<XPathItem>), // XmlTypeCode.None
typeof(IList<XPathItem>), // XmlTypeCode.Item
typeof(IList<XPathNavigator>), // XmlTypeCode.Node
typeof(IList<XPathNavigator>), // XmlTypeCode.Document
typeof(IList<XPathNavigator>), // XmlTypeCode.Element
typeof(IList<XPathNavigator>), // XmlTypeCode.Attribute
typeof(IList<XPathNavigator>), // XmlTypeCode.Namespace
typeof(IList<XPathNavigator>), // XmlTypeCode.ProcessingInstruction
typeof(IList<XPathNavigator>), // XmlTypeCode.Comment
typeof(IList<XPathNavigator>), // XmlTypeCode.Text
typeof(IList<XPathItem>), // XmlTypeCode.AnyAtomicType
typeof(IList<string>), // XmlTypeCode.UntypedAtomic
typeof(IList<string>), // XmlTypeCode.String
typeof(IList<bool>), // XmlTypeCode.Boolean
typeof(IList<decimal>), // XmlTypeCode.Decimal
typeof(IList<float>), // XmlTypeCode.Float
typeof(IList<double>), // XmlTypeCode.Double
typeof(IList<string>), // XmlTypeCode.Duration
typeof(IList<DateTime>), // XmlTypeCode.DateTime
typeof(IList<DateTime>), // XmlTypeCode.Time
typeof(IList<DateTime>), // XmlTypeCode.Date
typeof(IList<DateTime>), // XmlTypeCode.GYearMonth
typeof(IList<DateTime>), // XmlTypeCode.GYear
typeof(IList<DateTime>), // XmlTypeCode.GMonthDay
typeof(IList<DateTime>), // XmlTypeCode.GDay
typeof(IList<DateTime>), // XmlTypeCode.GMonth
typeof(IList<byte[]>), // XmlTypeCode.HexBinary
typeof(IList<byte[]>), // XmlTypeCode.Base64Binary
typeof(IList<string>), // XmlTypeCode.AnyUri
typeof(IList<XmlQualifiedName>), // XmlTypeCode.QName
typeof(IList<XmlQualifiedName>), // XmlTypeCode.Notation
typeof(IList<string>), // XmlTypeCode.NormalizedString
typeof(IList<string>), // XmlTypeCode.Token
typeof(IList<string>), // XmlTypeCode.Language
typeof(IList<string>), // XmlTypeCode.NmToken
typeof(IList<string>), // XmlTypeCode.Name
typeof(IList<string>), // XmlTypeCode.NCName
typeof(IList<string>), // XmlTypeCode.Id
typeof(IList<string>), // XmlTypeCode.Idref
typeof(IList<string>), // XmlTypeCode.Entity
typeof(IList<long>), // XmlTypeCode.Integer
typeof(IList<decimal>), // XmlTypeCode.NonPositiveInteger
typeof(IList<decimal>), // XmlTypeCode.NegativeInteger
typeof(IList<long>), // XmlTypeCode.Long
typeof(IList<int>), // XmlTypeCode.Int
typeof(IList<int>), // XmlTypeCode.Short
typeof(IList<int>), // XmlTypeCode.Byte
typeof(IList<decimal>), // XmlTypeCode.NonNegativeInteger
typeof(IList<decimal>), // XmlTypeCode.UnsignedLong
typeof(IList<long>), // XmlTypeCode.UnsignedInt
typeof(IList<int>), // XmlTypeCode.UnsignedShort
typeof(IList<int>), // XmlTypeCode.UnsignedByte
typeof(IList<decimal>), // XmlTypeCode.PositiveInteger
typeof(IList<TimeSpan>), // XmlTypeCode.YearMonthDuration
typeof(IList<TimeSpan>), // XmlTypeCode.DayTimeDuration
};
}
}

View File

@@ -0,0 +1 @@
786be8983fcf729e04fe03010b521bd7b8ee8d84

View File

@@ -0,0 +1,243 @@
//------------------------------------------------------------------------------
// <copyright file="ListBase.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Xml;
using System.Xml.Schema;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace System.Xml.Xsl {
/// <summary>
/// Implementation of read-only IList and IList<T> interfaces. Derived classes can inherit from
/// this class and implement only two methods, Count and Item, rather than the entire IList interface.
/// </summary>
internal abstract class ListBase<T> : IList<T>, System.Collections.IList {
//-----------------------------------------------
// Abstract IList methods that must be
// implemented by derived classes
//-----------------------------------------------
public abstract int Count { get; }
public abstract T this[int index] { get; set; }
//-----------------------------------------------
// Implemented by base class -- accessible on
// ListBase
//-----------------------------------------------
public virtual bool Contains(T value) {
return IndexOf(value) != -1;
}
public virtual int IndexOf(T value) {
for (int i = 0; i < Count; i++)
if (value.Equals(this[i]))
return i;
return -1;
}
public virtual void CopyTo(T[] array, int index) {
for (int i = 0; i < Count; i++)
array[index + i] = this[i];
}
public virtual IListEnumerator<T> GetEnumerator() {
return new IListEnumerator<T>(this);
}
public virtual bool IsFixedSize {
get { return true; }
}
public virtual bool IsReadOnly {
get { return true; }
}
public virtual void Add(T value) {
Insert(Count, value);
}
public virtual void Insert(int index, T value) {
throw new NotSupportedException();
}
public virtual bool Remove(T value) {
int index = IndexOf(value);
if (index >= 0) {
RemoveAt(index);
return true;
}
return false;
}
public virtual void RemoveAt(int index) {
throw new NotSupportedException();
}
public virtual void Clear() {
for (int index = Count - 1; index >= 0; index--)
RemoveAt(index);
}
//-----------------------------------------------
// Implemented by base class -- only accessible
// after casting to IList
//-----------------------------------------------
IEnumerator<T> IEnumerable<T>.GetEnumerator() {
return new IListEnumerator<T>(this);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return new IListEnumerator<T>(this);
}
bool System.Collections.ICollection.IsSynchronized {
get { return IsReadOnly; }
}
object System.Collections.ICollection.SyncRoot {
get { return this; }
}
void System.Collections.ICollection.CopyTo(Array array, int index) {
for (int i = 0; i < Count; i++)
array.SetValue(this[i], index);
}
object System.Collections.IList.this[int index] {
get { return this[index]; }
set {
if (!IsCompatibleType(value.GetType()))
throw new ArgumentException(Res.GetString(Res.Arg_IncompatibleParamType), "value");
this[index] = (T) value;
}
}
int System.Collections.IList.Add(object value) {
if (!IsCompatibleType(value.GetType()))
throw new ArgumentException(Res.GetString(Res.Arg_IncompatibleParamType), "value");
Add((T) value);
return Count - 1;
}
void System.Collections.IList.Clear() {
Clear();
}
bool System.Collections.IList.Contains(object value) {
if (!IsCompatibleType(value.GetType()))
return false;
return Contains((T) value);
}
int System.Collections.IList.IndexOf(object value) {
if (!IsCompatibleType(value.GetType()))
return -1;
return IndexOf((T) value);
}
void System.Collections.IList.Insert(int index, object value) {
if (!IsCompatibleType(value.GetType()))
throw new ArgumentException(Res.GetString(Res.Arg_IncompatibleParamType), "value");
Insert(index, (T) value);
}
void System.Collections.IList.Remove(object value) {
if (IsCompatibleType(value.GetType())) {
Remove((T)value);
}
}
//-----------------------------------------------
// Helper methods and classes
//-----------------------------------------------
private static bool IsCompatibleType(object value) {
if((value == null && !typeof(T).IsValueType) || (value is T))
return true;
return false;
}
}
/// <summary>
/// Implementation of IEnumerator<T> and IEnumerator over an IList<T>.
/// </summary>
internal struct IListEnumerator<T> : IEnumerator<T>, System.Collections.IEnumerator {
private IList<T> sequence;
private int index;
private T current;
/// <summary>
/// Constructor.
/// </summary>
public IListEnumerator(IList<T> sequence) {
this.sequence = sequence;
this.index = 0;
this.current = default(T);
}
/// <summary>
/// No-op.
/// </summary>
public void Dispose() {
}
/// <summary>
/// Return current item. Return default value if before first item or after last item in the list.
/// </summary>
public T Current {
get { return this.current; }
}
/// <summary>
/// Return current item. Throw exception if before first item or after last item in the list.
/// </summary>
object System.Collections.IEnumerator.Current {
get {
if (this.index == 0)
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
if (this.index > this.sequence.Count)
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
return this.current;
}
}
/// <summary>
/// Advance enumerator to next item in list. Return false if there are no more items.
/// </summary>
public bool MoveNext() {
if (this.index < this.sequence.Count) {
this.current = this.sequence[this.index];
this.index++;
return true;
}
this.current = default(T);
return false;
}
/// <summary>
/// Set the enumerator to its initial position, which is before the first item in the list.
/// </summary>
void System.Collections.IEnumerator.Reset() {
this.index = 0;
this.current = default(T);
}
}
}

View File

@@ -0,0 +1,51 @@
//------------------------------------------------------------------------------
// <copyright file="Pair.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
namespace System.Xml.Xsl {
internal struct Int32Pair {
private int left;
private int right;
public Int32Pair(int left, int right) {
this.left = left;
this.right = right;
}
public int Left { get { return this.left ; } }
public int Right { get { return this.right; } }
public override bool Equals(object other) {
if (other is Int32Pair) {
Int32Pair o = (Int32Pair) other;
return this.left == o.left && this.right == o.right;
}
return false;
}
public override int GetHashCode() {
return this.left.GetHashCode() ^ this.right.GetHashCode();
}
}
internal struct StringPair {
private string left;
private string right;
public StringPair(string left, string right) {
this.left = left;
this.right = right;
}
public string Left { get { return this.left ; } }
public string Right { get { return this.right; } }
}
}

View File

@@ -0,0 +1,76 @@
//------------------------------------------------------------------------------
// <copyright file="QilBinary.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Xml.Xsl.Qil {
/// <summary>
/// View over a Qil operator having two children.
/// </summary>
/// <remarks>
/// Don't construct QIL nodes directly; instead, use the <see cref="QilFactory">QilFactory</see>.
/// </remarks>
internal class QilBinary : QilNode {
private QilNode left, right;
//-----------------------------------------------
// Constructor
//-----------------------------------------------
/// <summary>
/// Construct a new node
/// </summary>
public QilBinary(QilNodeType nodeType, QilNode left, QilNode right) : base(nodeType) {
this.left = left;
this.right = right;
}
//-----------------------------------------------
// IList<QilNode> methods -- override
//-----------------------------------------------
public override int Count {
get { return 2; }
}
public override QilNode this[int index] {
get {
switch (index) {
case 0: return this.left;
case 1: return this.right;
default: throw new IndexOutOfRangeException();
}
}
set {
switch (index) {
case 0: this.left = value; break;
case 1: this.right = value; break;
default: throw new IndexOutOfRangeException();
}
}
}
//-----------------------------------------------
// QilBinary methods
//-----------------------------------------------
public QilNode Left {
get { return this.left; }
set { this.left = value; }
}
public QilNode Right {
get { return this.right; }
set { this.right = value; }
}
}
}

View File

@@ -0,0 +1,48 @@
//------------------------------------------------------------------------------
// <copyright file="QilLoop.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Diagnostics;
using System.Xml.Schema;
using System.Xml.Xsl;
namespace System.Xml.Xsl.Qil {
/// <summary>
/// View over a Qil choice operator.
/// </summary>
/// <remarks>
/// Don't construct QIL nodes directly; instead, use the <see cref="QilFactory">QilFactory</see>.
/// </remarks>
internal class QilChoice : QilBinary {
//-----------------------------------------------
// Constructor
//-----------------------------------------------
/// <summary>
/// Construct a new node
/// </summary>
public QilChoice(QilNodeType nodeType, QilNode expression, QilNode branches) : base(nodeType, expression, branches) {
}
//-----------------------------------------------
// QilChoice methods
//-----------------------------------------------
public QilNode Expression {
get { return Left; }
set { Left = value; }
}
public QilList Branches {
get { return (QilList) Right; }
set { Right = value; }
}
}
}

Some files were not shown because too many files have changed in this diff Show More