protected virtual T VisitChildren(XslNode node) { foreach (XslNode child in node.Content) { this.Visit(child); } return(default(T)); }
protected virtual T VisitNop(XslNode node) { return(VisitChildren(node)); }
protected virtual T VisitLiteralElement(XslNode node) { return(VisitChildren(node)); }
protected virtual T VisitForEach(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileLiteralElement(XslNode node) { // IlGen requires that namespace declarations do not conflict with the namespace used by the element // constructor, see XmlILNamespaceAnalyzer.CheckNamespaceInScope() and SQLBUDT 389481, 389482. First // we try to replace all prefixes bound to aliases by result-prefixes of the corresponding // xsl:namespace-alias instructions. If there is at least one conflict, we leave all prefixes // untouched, changing only namespace URIs. bool changePrefixes = true; Start: _prefixesInUse.Clear(); QilName qname = node.Name; string prefix = qname.Prefix; string nsUri = qname.NamespaceUri; _compiler.ApplyNsAliases(ref prefix, ref nsUri); if (changePrefixes) { _prefixesInUse.Add(prefix, nsUri); } else { prefix = qname.Prefix; } _outputScope.PushScope(); // Declare all namespaces that should be declared // <spec>http://www.w3.org/TR/xslt.html#literal-result-element</spec> QilList nsList = InstructionList(); foreach (ScopeRecord rec in _scope) { string recPrefix = rec.ncName; string recNsUri = rec.nsUri; if (recNsUri != XmlReservedNs.NsXslt && !_scope.IsExNamespace(recNsUri)) { _compiler.ApplyNsAliases(ref recPrefix, ref recNsUri); if (changePrefixes) { if (_prefixesInUse.Contains(recPrefix)) { if ((string)_prefixesInUse[recPrefix] != recNsUri) { // Found a prefix conflict. Start again from the beginning leaving all prefixes untouched. _outputScope.PopScope(); changePrefixes = false; goto Start; } } else { _prefixesInUse.Add(recPrefix, recNsUri); } } else { recPrefix = rec.ncName; } AddNsDecl(nsList, recPrefix, recNsUri); } } QilNode content = CompileInstructions(node.Content, nsList); _outputScope.PopScope(); qname.Prefix = prefix; qname.NamespaceUri = nsUri; return _f.ElementCtor(qname, content); }
internal static XslNode SetInfo(XslNode to, List<XslNode> content, ContextInfo info) { Debug.Assert(to != null); to.Namespaces = info.nsList; SetContent(to, content); SetLineInfo(to, info.lineInfo); return to; }
private void CheckWithParam(List<XslNode> content, XslNode withParam) { Debug.Assert(content != null && withParam != null); Debug.Assert(withParam.NodeType == XslNodeType.WithParam); foreach (XslNode node in content) { if (node.NodeType == XslNodeType.WithParam && node.Name.Equals(withParam.Name)) { ReportError(/*[XT0670]*/SR.Xslt_DuplicateWithParam, withParam.Name.QualifiedName); break; } } }
protected virtual T VisitApplyImports(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileApplyImports(XslNode node) { Debug.Assert(node.NodeType == XslNodeType.ApplyImports); Debug.Assert(!_curLoop.IsFocusSet, "xsl:apply-imports cannot be inside of xsl:for-each"); return GenerateApply((StylesheetLevel)node.Arg, node); }
private QilNode CompileError(XslNode node) { return _f.Error(_f.String(node.Select)); }
private QilNode CompileComment(XslNode node) { return _f.CommentCtor(CompileInstructions(node.Content)); }
private QilNode CompilePI(XslNode node) { QilNode qilName = CompileStringAvt(node.Select); if (qilName.NodeType == QilNodeType.LiteralString) { string name = (string)(QilLiteral)qilName; _compiler.ValidatePiName(name, (IErrorHelper)this); } return _f.PICtor(qilName, CompileInstructions(node.Content)); }
private QilList EnterScope(XslNode node) { // This is the only place where lastScope is changed lastScope = node; xslVersion = node.XslVersion; this.scope.PushScope(); bool hasNamespaces = false; NsDecl nsDecl = node.Namespaces; while (nsDecl != null) { Debug.Assert(nsDecl.NsUri != null); this.scope.AddNamespace(nsDecl.Prefix, nsDecl.NsUri); nsDecl = nsDecl.Prev; hasNamespaces = true; } if (hasNamespaces) { return BuildDebuggerNamespaces(); } return null; }
private void AddImplicitArgs(XslNode node) { Debug.Assert( node.NodeType == XslNodeType.CallTemplate || node.NodeType == XslNodeType.UseAttributeSet || node.NodeType == XslNodeType.ApplyTemplates || node.NodeType == XslNodeType.ApplyImports ); XslFlags flags = 0; if (IsDebug) { flags = XslFlags.FullFocus; } else { if (node.NodeType == XslNodeType.CallTemplate) { Template tmpl; if (compiler.NamedTemplates.TryGetValue(node.Name, out tmpl)) { flags = tmpl.Flags; } } else if (node.NodeType == XslNodeType.UseAttributeSet) { AttributeSet attSet; if (compiler.AttributeSets.TryGetValue(node.Name, out attSet)) { flags = attSet.Flags; } } else { if (! compiler.ModeFlags.TryGetValue(node.Name, out flags)) { flags = 0; } // Due to recursive nature of xsl:apply-templates/imports we always need current node flags |= XslFlags.Current; } } List<XslNode> implicitArgs = new List<XslNode>(); { if ((flags & XslFlags.Current ) != 0) { implicitArgs.Add(CreateWithParam(nameCurrent , GetCurrentNode() )); } if ((flags & XslFlags.Position) != 0) { implicitArgs.Add(CreateWithParam(namePosition, GetCurrentPosition())); } if ((flags & XslFlags.Last ) != 0) { implicitArgs.Add(CreateWithParam(nameLast , GetLastPosition() )); } }; node.InsertContent(implicitArgs); }
private QilNode GenerateApply(Stylesheet sheet, XslNode node) { Debug.Assert( node.NodeType == XslNodeType.ApplyTemplates || node.NodeType == XslNodeType.ApplyImports ); if (compiler.Settings.CheckOnly) { return f.Sequence(); } AddImplicitArgs(node); return InvokeApplyFunction(sheet, /*mode:*/node.Name, node.Content); }
protected virtual T VisitUseAttributeSet(XslNode node) { return(VisitChildren(node)); }
protected virtual T VisitUnknown(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileUseAttributeSet(XslNode node) { VerifyXPathQName(node.Name); // REVIEW: Future optimization: invalidate only if there were AVTs _outputScope.InvalidateAllPrefixes(); AttributeSet attSet; if (_compiler.AttributeSets.TryGetValue(node.Name, out attSet)) { Debug.Assert(attSet.Function != null, "All templates should be already compiled"); return _invkGen.GenerateInvoke(attSet.Function, AddRemoveImplicitArgs(node.Content, attSet.Flags)); } else { if (!_compiler.IsPhantomName(node.Name)) { _compiler.ReportError(/*[XT0710]*/node.SourceLine, SR.Xslt_NoAttributeSet, node.Name.QualifiedName); } return _f.Sequence(); } }
protected virtual T VisitApplyTemplates(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileCopy(XslNode copy) { QilNode node = GetCurrentNode(); _f.CheckNodeNotRtf(node); if ((node.XmlType.NodeKinds & InvalidatingNodes) != XmlNodeKindFlags.None) { _outputScope.InvalidateAllPrefixes(); } if (node.XmlType.NodeKinds == XmlNodeKindFlags.Element) { // Context node is always an element // The namespace nodes of the current node are automatically copied QilList content = InstructionList(); content.Add(_f.XPathNamespace(node)); _outputScope.PushScope(); _outputScope.InvalidateAllPrefixes(); QilNode result = CompileInstructions(copy.Content, content); _outputScope.PopScope(); return _f.ElementCtor(_f.NameOf(node), result); } else if (node.XmlType.NodeKinds == XmlNodeKindFlags.Document) { // Context node is always a document // xsl:copy will not create a document node, but will just use the content template return CompileInstructions(copy.Content); } else if ((node.XmlType.NodeKinds & (XmlNodeKindFlags.Element | XmlNodeKindFlags.Document)) == XmlNodeKindFlags.None) { // Context node is neither an element, nor a document // The content of xsl:copy is not instantiated return node; } else { // Static classifying of the context node is not possible return _f.XsltCopy(node, CompileInstructions(copy.Content)); } }
private static XslNode SetLineInfo(XslNode node, ISourceLineInfo lineInfo) { Debug.Assert(node != null); node.SourceLine = lineInfo; return node; }
private QilNode CompileCopyOf(XslNode node) { QilNode selectExpr = CompileXPathExpression(node.Select); if (selectExpr.XmlType.IsNode) { if ((selectExpr.XmlType.NodeKinds & InvalidatingNodes) != XmlNodeKindFlags.None) { _outputScope.InvalidateAllPrefixes(); } if (selectExpr.XmlType.IsNotRtf && (selectExpr.XmlType.NodeKinds & XmlNodeKindFlags.Document) == XmlNodeKindFlags.None) { // Expression returns non-document nodes only return selectExpr; } // May be an Rtf or may return Document nodes, so use XsltCopyOf operator if (selectExpr.XmlType.IsSingleton) { return _f.XsltCopyOf(selectExpr); } else { QilIterator it; return _f.Loop(it = _f.For(selectExpr), _f.XsltCopyOf(it)); } } else if (selectExpr.XmlType.IsAtomicValue) { // Expression returns non-nodes only // When the result is neither a node-set nor a result tree fragment, the result is converted // to a string and then inserted into the result tree, as with xsl:value-of. return _f.TextCtor(_f.ConvertToString(selectExpr)); } else { // Static classifying is not possible QilIterator it; _outputScope.InvalidateAllPrefixes(); return _f.Loop( it = _f.For(selectExpr), _f.Conditional(_f.IsType(it, T.Node), _f.XsltCopyOf(_f.TypeAssert(it, T.Node)), _f.TextCtor(_f.XsltConvert(it, T.StringX)) ) ); } }
// ----------------- use-attribute-sets, call-templates, apply-templates, apply-imports ----------------------------- // private QilNode GenerateCall(QilFunction func, XslNode node) { Debug.Assert( node.NodeType == XslNodeType.CallTemplate || node.NodeType == XslNodeType.UseAttributeSet ); AddImplicitArgs(node); return invkGen.GenerateInvoke(func, node.Content); }
private QilNode CompileValueOfDoe(XslNode valueOf) { return _f.RawTextCtor(_f.ConvertToString(CompileXPathExpression(/*select:*/valueOf.Select))); }
private QilNode CompileLiteralAttribute(XslNode node) { QilName qname = node.Name; string prefix = qname.Prefix; string nsUri = qname.NamespaceUri; // The default namespace do not apply directly to attributes if (prefix.Length != 0) { _compiler.ApplyNsAliases(ref prefix, ref nsUri); } qname.Prefix = prefix; qname.NamespaceUri = nsUri; return _f.AttributeCtor(qname, CompileTextAvt(node.Select)); }
private QilNode CompileWhen(XslNode whenNode, QilNode otherwise) { return _f.Conditional( _f.ConvertToBoolean(CompileXPathExpression(/*test:*/whenNode.Select)), CompileInstructions(whenNode.Content), otherwise ); }
protected virtual T VisitLiteralAttribute(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileIf(XslNode ifNode) { return CompileWhen(ifNode, InstructionList()); }
protected virtual T VisitMessage(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileChoose(XslNode node) { IList<XslNode> cases = node.Content; QilNode result = null; // It's easier to compile xsl:choose from bottom to top for (int i = cases.Count - 1; 0 <= i; i--) { XslNode when = cases[i]; Debug.Assert(when.NodeType == XslNodeType.If || when.NodeType == XslNodeType.Otherwise); QilList nsList = EnterScope(when); if (when.NodeType == XslNodeType.Otherwise) { Debug.Assert(result == null, "xsl:otherwise must be the last child of xsl:choose"); result = CompileInstructions(when.Content); } else { result = CompileWhen(when, /*otherwise:*/result ?? InstructionList()); } ExitScope(); SetLineInfoCheck(result, when.SourceLine); result = SetDebugNs(result, nsList); } if (result == null) { return _f.Sequence(); } return IsDebug ? _f.Sequence(result) : result; }
protected virtual T VisitOtherwise(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileMessage(XslNode node) { string baseUri = _lastScope.SourceLine.Uri; QilNode content = _f.RtfCtor(CompileInstructions(node.Content), _f.String(baseUri)); //content = f.ConvertToString(content); content = _f.InvokeOuterXml(content); // If terminate="no", then create QilNodeType.Warning if (!(bool)node.Arg) { return _f.Warning(content); } // Otherwise create both QilNodeType.Warning and QilNodeType.Error QilIterator i; return _f.Loop(i = _f.Let(content), _f.Sequence(_f.Warning(i), _f.Error(i))); }
protected virtual T VisitValueOfDoe(XslNode node) { return(VisitChildren(node)); }
private QilNode CompileVariable(XslNode node) { Debug.Assert(node.NodeType == XslNodeType.Variable); if (_scope.IsLocalVariable(node.Name.LocalName, node.Name.NamespaceUri)) { ReportError(/*[XT_030]*/SR.Xslt_DupLocalVariable, node.Name.QualifiedName); } return CompileVarParValue(node); }
private QilNode CompileVarParValue(XslNode node) { Debug.Assert(node.NodeType == XslNodeType.Variable || node.NodeType == XslNodeType.Param || node.NodeType == XslNodeType.WithParam); VerifyXPathQName(node.Name); string baseUri = _lastScope.SourceLine.Uri; IList<XslNode> content = node.Content; string select = node.Select; QilNode varValue; if (select != null) { // In case of incorrect stylesheet, variable or parameter may have both a 'select' attribute and non-empty content QilList list = InstructionList(); list.Add(CompileXPathExpression(select)); varValue = CompileInstructions(content, list); } else if (content.Count != 0) { _outputScope.PushScope(); // Rtf will be instantiated in an unknown namespace context, so we should not assume anything here _outputScope.InvalidateAllPrefixes(); varValue = _f.RtfCtor(CompileInstructions(content), _f.String(baseUri)); _outputScope.PopScope(); } else { varValue = _f.String(string.Empty); } if (IsDebug) { // In debug mode every variable/param must be of type 'any' varValue = _f.TypeAssert(varValue, T.ItemS); } Debug.Assert(varValue.SourceLine == null); return varValue; }
// ----------------- apply-templates, apply-imports ----------------------------- // private QilNode GenerateApply(StylesheetLevel sheet, XslNode node) { Debug.Assert( node.NodeType == XslNodeType.ApplyTemplates && sheet is RootLevel || node.NodeType == XslNodeType.ApplyImports && sheet is Stylesheet ); if (_compiler.Settings.CheckOnly) { return _f.Sequence(); } return InvokeApplyFunction(sheet, /*mode:*/node.Name, node.Content); }
protected virtual T Visit(XslNode node) { switch (node.NodeType) { case XslNodeType.ApplyImports: return(VisitApplyImports((XslNode)node)); case XslNodeType.ApplyTemplates: return(VisitApplyTemplates((XslNode)node)); case XslNodeType.Attribute: return(VisitAttribute((NodeCtor)node)); case XslNodeType.AttributeSet: return(VisitAttributeSet((AttributeSet)node)); case XslNodeType.CallTemplate: return(VisitCallTemplate((XslNode)node)); case XslNodeType.Choose: return(VisitChoose((XslNode)node)); case XslNodeType.Comment: return(VisitComment((XslNode)node)); case XslNodeType.Copy: return(VisitCopy((XslNode)node)); case XslNodeType.CopyOf: return(VisitCopyOf((XslNode)node)); case XslNodeType.Element: return(VisitElement((NodeCtor)node)); case XslNodeType.Error: return(VisitError((XslNode)node)); case XslNodeType.ForEach: return(VisitForEach((XslNode)node)); case XslNodeType.If: return(VisitIf((XslNode)node)); case XslNodeType.Key: return(VisitKey((Key)node)); case XslNodeType.List: return(VisitList((XslNode)node)); case XslNodeType.LiteralAttribute: return(VisitLiteralAttribute((XslNode)node)); case XslNodeType.LiteralElement: return(VisitLiteralElement((XslNode)node)); case XslNodeType.Message: return(VisitMessage((XslNode)node)); case XslNodeType.Nop: return(VisitNop((XslNode)node)); case XslNodeType.Number: return(VisitNumber((Number)node)); case XslNodeType.Otherwise: return(VisitOtherwise((XslNode)node)); case XslNodeType.Param: return(VisitParam((VarPar)node)); case XslNodeType.PI: return(VisitPI((XslNode)node)); case XslNodeType.Sort: return(VisitSort((Sort)node)); case XslNodeType.Template: return(VisitTemplate((Template)node)); case XslNodeType.Text: return(VisitText((Text)node)); case XslNodeType.UseAttributeSet: return(VisitUseAttributeSet((XslNode)node)); case XslNodeType.ValueOf: return(VisitValueOf((XslNode)node)); case XslNodeType.ValueOfDoe: return(VisitValueOfDoe((XslNode)node)); case XslNodeType.Variable: return(VisitVariable((VarPar)node)); case XslNodeType.WithParam: return(VisitWithParam((VarPar)node)); default: return(VisitUnknown((XslNode)node)); } }
private QilNode CompileRootExpression(XslNode applyTmpls) { // Compile start apply-templates call CheckSingletonFocus(); _singlFocus.SetFocus(SingletonFocusType.InitialContextNode); QilNode result = GenerateApply(_compiler.Root, applyTmpls); _singlFocus.SetFocus(null); return _f.DocumentCtor(result); }
protected virtual T VisitCallTemplate(XslNode node) { return(VisitChildren(node)); }
private QilList EnterScope(XslNode node) { // This is the only place where lastScope is changed _lastScope = node; _xslVersion = node.XslVersion; if (_scope.EnterScope(node.Namespaces)) { return BuildDebuggerNamespaces(); } return null; }
private static void AddInstruction(List<XslNode> content, XslNode instruction) { Debug.Assert(content != null); if (instruction != null) { content.Add(instruction); } }
private QilNode CompileList(XslNode node) { return CompileInstructions(node.Content); }
private static void SetContent(XslNode node, List<XslNode> content) { Debug.Assert(node != null); if (content != null && content.Count == 0) { content = null; // Actualy we can reuse this ArrayList. } node.SetContent(content); }
private QilNode CompileNop(XslNode node) { return _f.Nop(_f.Sequence()); }
public WebresourceNode AddSingleNode(Webresource resource, string[] nameParts, FolderNode folder = null) { var fileName = nameParts.Last(); WebresourceType type = WebresourceType.Auto; if (resource.Type != 0) { type = (WebresourceType)resource.Type; } if (type == WebresourceType.Auto) { if (fileName.IndexOf(".", StringComparison.Ordinal) < 0) { if (resource.Type == 0) { return(null); } type = (WebresourceType)resource.Type; } else { type = Webresource.GetTypeFromExtension(fileName .Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Last()); } } WebresourceNode node = null; switch (type) { case WebresourceType.WebPage: node = new WebpageNode(resource, Settings); break; case WebresourceType.Css: node = new CssNode(resource, Settings); break; case WebresourceType.Data: node = new DataNode(resource, Settings); break; case WebresourceType.Gif: node = new GifNode(resource, Settings); break; case WebresourceType.Ico: node = new IcoNode(resource, Settings); break; case WebresourceType.Jpg: node = new JpgNode(resource, Settings); break; case WebresourceType.Png: node = new PngNode(resource, Settings); break; case WebresourceType.Resx: node = new ResxNode(resource, Settings); break; case WebresourceType.Script: node = new JavaScriptNode(resource, Settings); break; case WebresourceType.Silverlight: node = new SilverlightNode(resource, Settings); break; case WebresourceType.Vector: node = new VectorNode(resource, Settings); break; case WebresourceType.Xsl: node = new XslNode(resource, Settings); break; } resource.Node = node; if (folder != null && node != null) { node.ForeColor = resource.State == WebresourceState.Saved ? Color.Blue : resource.State == WebresourceState.Draft ? Color.Red : Color.Black; folder.Nodes.Add(node); (node.Parent as FolderNode)?.SetFolderColor(); } return(node); }
protected virtual T Visit(XslNode node) => node.NodeType switch {