Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / XmlUtils / System / Xml / Xsl / Xslt / InvokeGenerator.cs / 1305376 / InvokeGenerator.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.Xsl.Qil;
namespace System.Xml.Xsl.Xslt {
using T = XmlQueryTypeFactory;
/**
InvokeGenerator is one of the trikest peaces here.
ARGS:
QilFunction func -- Functions which should be invoked. Arguments of this function (formalArgs) are Let nodes
anotated with names and default valies.
Problem 1 is that default values can contain references to previouse args of this function.
Problem 2 is that default values shouldn't contain fixup nodes.
ArrayList actualArgs -- Array of QilNodes anotated with names. When name of formalArg match name actualArg last one
is used as invokeArg, otherwise formalArg's default value is cloned and used.
**/
internal class InvokeGenerator : QilCloneVisitor {
private bool debug;
private Stack iterStack;
private QilList formalArgs;
private QilList invokeArgs;
private int curArg; // this.Clone() depends on this value
private XsltQilFactory fac;
public InvokeGenerator(XsltQilFactory f, bool debug) : base(f.BaseFactory) {
this.debug = debug;
this.fac = f;
this.iterStack = new Stack();
}
public QilNode GenerateInvoke(QilFunction func, IList actualArgs) {
iterStack.Clear();
formalArgs = func.Arguments;
invokeArgs = fac.ActualParameterList();
// curArg is an instance variable used in Clone() method
for (curArg = 0; curArg < formalArgs.Count; curArg ++) {
// Find actual value for a given formal arg
QilParameter formalArg = (QilParameter)formalArgs[curArg];
QilNode invokeArg = FindActualArg(formalArg, actualArgs);
// If actual value was not specified, use the default value and copy its debug comment
if (invokeArg == null) {
if (debug) {
if (formalArg.Name.NamespaceUri == XmlReservedNs.NsXslDebug) {
Debug.Assert(formalArg.Name.LocalName == "namespaces", "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs()");
Debug.Assert(formalArg.DefaultValue != null, "PrecompileProtoTemplatesHeaders() set it");
invokeArg = Clone(formalArg.DefaultValue);
} else {
invokeArg = fac.DefaultValueMarker();
}
} else {
Debug.Assert(formalArg.Name.NamespaceUri != XmlReservedNs.NsXslDebug, "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs(). We don't have $namespaces in !debug.");
invokeArg = Clone(formalArg.DefaultValue);
}
}
XmlQueryType formalType = formalArg.XmlType;
XmlQueryType invokeType = invokeArg.XmlType;
// Possible arg types: anyType, node-set, string, boolean, and number
fac.CheckXsltType(formalArg);
fac.CheckXsltType(invokeArg);
if (!invokeType.IsSubtypeOf(formalType)) {
// This may occur only if inferred type of invokeArg is XslFlags.None
Debug.Assert(invokeType == T.ItemS, "Actual argument type is not a subtype of formal argument type");
invokeArg = fac.TypeAssert(invokeArg, formalType);
}
invokeArgs.Add(invokeArg);
}
// Create Invoke node and wrap it with previous parameter declarations
QilNode invoke = fac.Invoke(func, invokeArgs);
while (iterStack.Count != 0)
invoke = fac.Loop(iterStack.Pop(), invoke);
return invoke;
}
private QilNode FindActualArg(QilParameter formalArg, IList actualArgs) {
QilName argName = formalArg.Name;
Debug.Assert(argName != null);
foreach (XslNode actualArg in actualArgs) {
if (actualArg.Name.Equals(argName)) {
return ((VarPar)actualArg).Value;
}
}
return null;
}
// ------------------------------------ QilCloneVisitor -------------------------------------
protected override QilNode VisitReference(QilNode n) {
QilNode replacement = FindClonedReference(n);
// If the reference is internal for the subtree being cloned, return it as is
if (replacement != null) {
return replacement;
}
// Replacement was not found, thus the reference is external for the subtree being cloned.
// The case when it refers to one of previous arguments (xsl:param can refer to previous
// xsl:param's) must be taken care of.
for (int prevArg = 0; prevArg < curArg; prevArg++) {
Debug.Assert(formalArgs[prevArg] != null, "formalArg must be in the list");
Debug.Assert(invokeArgs[prevArg] != null, "This arg should be compiled already");
// Is this a reference to prevArg?
if (n == formalArgs[prevArg]) {
// If prevArg is a literal, just clone it
if (invokeArgs[prevArg] is QilLiteral) {
return invokeArgs[prevArg].ShallowClone(fac.BaseFactory);
}
// If prevArg is not an iterator, cache it in an iterator, and return it
if (!(invokeArgs[prevArg] is QilIterator)) {
QilIterator var = fac.BaseFactory.Let(invokeArgs[prevArg]);
iterStack.Push(var);
invokeArgs[prevArg] = var;
}
Debug.Assert(invokeArgs[prevArg] is QilIterator);
return invokeArgs[prevArg];
}
}
// This is a truly external reference, return it as is
return n;
}
protected override QilNode VisitFunction(QilFunction n) {
// No need to change function references
return n;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SQlBooleanStorage.cs
- UrlMapping.cs
- PropertyRecord.cs
- TimeZone.cs
- XmlImplementation.cs
- NullReferenceException.cs
- FullTextState.cs
- DataSourceXmlElementAttribute.cs
- EventLogPermissionEntryCollection.cs
- SqlParameterCollection.cs
- ReflectionTypeLoadException.cs
- EntityTemplateUserControl.cs
- NameGenerator.cs
- DrawingVisualDrawingContext.cs
- CustomActivityDesigner.cs
- ParseChildrenAsPropertiesAttribute.cs
- PathTooLongException.cs
- DelimitedListTraceListener.cs
- RegexReplacement.cs
- WebPartCollection.cs
- AsymmetricCryptoHandle.cs
- Image.cs
- OleDbConnection.cs
- RowBinding.cs
- BindingExpressionUncommonField.cs
- ImageConverter.cs
- DataGridViewRowConverter.cs
- StringUtil.cs
- FromReply.cs
- HtmlTableRow.cs
- DataControlImageButton.cs
- RankException.cs
- Application.cs
- TextRunProperties.cs
- ResourceDefaultValueAttribute.cs
- UrlMappingsModule.cs
- PolyQuadraticBezierSegment.cs
- MimeMapping.cs
- COM2ColorConverter.cs
- ResumeStoryboard.cs
- AssemblyNameProxy.cs
- DataGridViewCellStateChangedEventArgs.cs
- TargetControlTypeCache.cs
- DataGridViewCellCancelEventArgs.cs
- WriteStateInfoBase.cs
- TraceProvider.cs
- UnsafeNativeMethods.cs
- HtmlProps.cs
- ElementNotEnabledException.cs
- DoubleAnimation.cs
- BitmapEffectState.cs
- VerificationAttribute.cs
- PopupEventArgs.cs
- MessagingDescriptionAttribute.cs
- GacUtil.cs
- SqlInternalConnectionTds.cs
- RefType.cs
- OleDbRowUpdatingEvent.cs
- LocationSectionRecord.cs
- BinaryNode.cs
- ReferencedCollectionType.cs
- SharedStream.cs
- ProxyHwnd.cs
- ToolStripManager.cs
- XsltCompileContext.cs
- Inline.cs
- NestedContainer.cs
- ToolStripItemTextRenderEventArgs.cs
- KnownTypesProvider.cs
- WsdlHelpGeneratorElement.cs
- RequestBringIntoViewEventArgs.cs
- SpecialNameAttribute.cs
- XmlAttributeOverrides.cs
- PropertyEmitterBase.cs
- ExclusiveTcpListener.cs
- CodeVariableReferenceExpression.cs
- MonitorWrapper.cs
- SmtpFailedRecipientException.cs
- WaitForChangedResult.cs
- FontStretch.cs
- CodeAttributeArgument.cs
- Matrix3D.cs
- SimpleBitVector32.cs
- TriggerAction.cs
- ZeroOpNode.cs
- SourceFileBuildProvider.cs
- ListChangedEventArgs.cs
- UnsafeNativeMethods.cs
- TextElementCollectionHelper.cs
- ManagedWndProcTracker.cs
- TableStyle.cs
- RequestQueryProcessor.cs
- WebPartConnectionsDisconnectVerb.cs
- XmlSchemaGroup.cs
- LinkUtilities.cs
- Condition.cs
- TimerElapsedEvenArgs.cs
- TextParaClient.cs
- ExtendedPropertyCollection.cs
- HeaderedContentControl.cs