From bb74407cfc11a1d3ff10d27315717c84c9790df2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 3 Jul 2010 06:05:52 +0000 Subject: [PATCH] finished VBNetOutputVisitor for XML Literals git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6021 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../NRefactoryASTGenerator/AST/Expressions.cs | 2 + .../NRefactory/Project/Src/Ast/Generated.cs | 21 ++- .../Project/Src/Parser/VBNet/Parser.cs | 6 +- .../Project/Src/Parser/VBNet/VBNET.ATG | 6 +- .../PrettyPrinter/VBNet/VBNetOutputVisitor.cs | 132 ++++++++++++++++-- .../Src/Visitors/AbstractASTVisitor.cs | 2 +- .../Src/Visitors/AbstractAstTransformer.cs | 11 ++ .../Test/Output/VBNet/VBNetOutputTest.cs | 79 ++++++++++- 8 files changed, 237 insertions(+), 22 deletions(-) diff --git a/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs b/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs index 7ab30c29d7..26289080bd 100644 --- a/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs +++ b/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs @@ -422,6 +422,7 @@ namespace NRefactoryASTGenerator.Ast [IncludeBoolProperty("IsExpression", "return !content.IsNull;")] [IncludeBoolProperty("NameIsExpression", "return !nameExpression.IsNull;")] + [HasChildren] class XmlElementExpression : XmlExpression { Expression content; Expression nameExpression; @@ -433,6 +434,7 @@ namespace NRefactoryASTGenerator.Ast class XmlAttribute : XmlExpression { string name; string literalValue; + bool useDoubleQuotes; Expression expressionValue; } } diff --git a/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs b/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs index 7a8d358721..78a167c8be 100644 --- a/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs +++ b/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs @@ -5464,6 +5464,8 @@ public UsingDeclaration(string @namespace, TypeReference alias) { usings = new L string literalValue; + bool useDoubleQuotes; + Expression expressionValue; public string Name { @@ -5484,6 +5486,15 @@ public UsingDeclaration(string @namespace, TypeReference alias) { usings = new L } } + public bool UseDoubleQuotes { + get { + return useDoubleQuotes; + } + set { + useDoubleQuotes = value; + } + } + public Expression ExpressionValue { get { return expressionValue; @@ -5511,7 +5522,7 @@ public UsingDeclaration(string @namespace, TypeReference alias) { usings = new L } public override string ToString() { - return string.Format("[XmlAttribute Name={0} LiteralValue={1} ExpressionValue={2}]", Name, LiteralValue, ExpressionValue); + return string.Format("[XmlAttribute Name={0} LiteralValue={1} UseDoubleQuotes={2} ExpressionValue={3}]", Name, LiteralValue, UseDoubleQuotes, ExpressionValue); } } @@ -5608,15 +5619,15 @@ public UsingDeclaration(string @namespace, TypeReference alias) { usings = new L attributes = new List(); } - public bool IsExpression { + public bool NameIsExpression { get { - return !content.IsNull; + return !nameExpression.IsNull; } } - public bool NameIsExpression { + public bool IsExpression { get { - return !nameExpression.IsNull; + return !content.IsNull; } } diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs index 44de216921..32f0b9d735 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs @@ -4757,12 +4757,12 @@ List attrs) { Expect(20); #line 1839 "VBNET.ATG" - string literalValue = null; Expression expressionValue = null; + string literalValue = null; Expression expressionValue = null; bool useDoubleQuotes = false; if (la.kind == 3) { lexer.NextToken(); #line 1840 "VBNET.ATG" - literalValue = t.literalValue.ToString(); + literalValue = t.literalValue.ToString(); useDoubleQuotes = t.val[0] == '"'; } else if (la.kind == 12) { lexer.NextToken(); Expr( @@ -4772,7 +4772,7 @@ out expressionValue); } else SynErr(290); #line 1841 "VBNET.ATG" - attrs.Add(new XmlAttribute() { Name = name, ExpressionValue = expressionValue, LiteralValue = literalValue, StartLocation = start, EndLocation = t.EndLocation }); + attrs.Add(new XmlAttribute() { Name = name, ExpressionValue = expressionValue, LiteralValue = literalValue, UseDoubleQuotes = useDoubleQuotes, StartLocation = start, EndLocation = t.EndLocation }); } else if (la.kind == 12) { lexer.NextToken(); diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG index 1e29ea1815..19bd777cba 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG @@ -1836,9 +1836,9 @@ XmlAttribute attrs> (. Location start = la.Location; .) = Identifier (. string name = t.val; .) "=" - (. string literalValue = null; Expression expressionValue = null; .) - ( LiteralString (. literalValue = t.literalValue.ToString(); .) | XmlStartInlineVB Expr XmlEndInlineVB ) - (. attrs.Add(new XmlAttribute() { Name = name, ExpressionValue = expressionValue, LiteralValue = literalValue, StartLocation = start, EndLocation = t.EndLocation }); .) + (. string literalValue = null; Expression expressionValue = null; bool useDoubleQuotes = false; .) + ( LiteralString (. literalValue = t.literalValue.ToString(); useDoubleQuotes = t.val[0] == '"'; .) | XmlStartInlineVB Expr XmlEndInlineVB ) + (. attrs.Add(new XmlAttribute() { Name = name, ExpressionValue = expressionValue, LiteralValue = literalValue, UseDoubleQuotes = useDoubleQuotes, StartLocation = start, EndLocation = t.EndLocation }); .) | XmlStartInlineVB (. Expression innerExpression; .) Expr XmlEndInlineVB (. attrs.Add(new XmlEmbeddedExpression() { InlineVBExpression = innerExpression, StartLocation = start, EndLocation = t.EndLocation }); .) diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs index 1907def20e..1c12f54512 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs @@ -2998,21 +2998,26 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.PrintToken(Tokens.Function); } - public override object TrackedVisitQueryExpression(QueryExpression queryExpression, object data) + public override object TrackedVisitQueryExpressionVB(QueryExpressionVB queryExpression, object data) { outputFormatter.IndentationLevel++; - queryExpression.MiddleClauses.ForEach(PrintClause); + for (int i = 0; i < queryExpression.Clauses.Count; i++) { + QueryExpressionClause clause = queryExpression.Clauses[i]; + if (!clause.IsNull) { + if (i != 0) { + outputFormatter.PrintLineContinuation(); + outputFormatter.Indent(); + } + clause.AcceptVisitor(this, null); + } + } outputFormatter.IndentationLevel--; return null; } void PrintClause(QueryExpressionClause clause) { - if (!clause.IsNull) { - outputFormatter.PrintLineContinuation(); - outputFormatter.Indent(); - clause.AcceptVisitor(this, null); - } + } public override object TrackedVisitQueryExpressionFromClause(QueryExpressionFromClause fromClause, object data) @@ -3111,15 +3116,19 @@ namespace ICSharpCode.NRefactory.PrettyPrinter return null; } - public override object TrackedVisitQueryExpressionSelectClause(QueryExpressionSelectClause selectClause, object data) + public override object TrackedVisitQueryExpressionSelectVBClause(QueryExpressionSelectVBClause selectClause, object data) { outputFormatter.PrintToken(Tokens.Select); outputFormatter.Space(); - return selectClause.Projection.AcceptVisitor(this, data); + foreach (ExpressionRangeVariable var in selectClause.Variables) { + var.AcceptVisitor(this, data); + } + return null; } public override object TrackedVisitQueryExpressionWhereClause(QueryExpressionWhereClause whereClause, object data) { + outputFormatter.Space(); outputFormatter.PrintText("Where"); outputFormatter.Space(); return whereClause.Condition.AcceptVisitor(this, data); @@ -3130,5 +3139,110 @@ namespace ICSharpCode.NRefactory.PrettyPrinter UnsupportedNode(externAliasDirective); return null; } + + public override object TrackedVisitXmlContentExpression(XmlContentExpression xmlContentExpression, object data) + { + switch (xmlContentExpression.Type) { + case XmlContentType.Comment: + outputFormatter.PrintText(""); + break; + case XmlContentType.Text: + outputFormatter.PrintText(xmlContentExpression.Content); + break; + case XmlContentType.CData: + outputFormatter.PrintText(""); + break; + case XmlContentType.ProcessingInstruction: + outputFormatter.PrintText(""); + break; + default: + throw new Exception("Invalid value for XmlContentType"); + } + return null; + } + + public override object TrackedVisitXmlEmbeddedExpression(XmlEmbeddedExpression xmlEmbeddedExpression, object data) + { + outputFormatter.PrintText("<%="); + outputFormatter.Space(); + xmlEmbeddedExpression.InlineVBExpression.AcceptVisitor(this, data); + outputFormatter.Space(); + outputFormatter.PrintText("%>"); + return null; + } + + public override object TrackedVisitXmlAttribute(XmlAttribute xmlAttribute, object data) + { + outputFormatter.PrintText(xmlAttribute.Name); + outputFormatter.PrintToken(Tokens.Assign); + if (xmlAttribute.IsLiteralValue) { + if (xmlAttribute.UseDoubleQuotes) + outputFormatter.PrintText("\""); + else + outputFormatter.PrintText("'"); + outputFormatter.PrintText(xmlAttribute.LiteralValue); + if (xmlAttribute.UseDoubleQuotes) + outputFormatter.PrintText("\""); + else + outputFormatter.PrintText("'"); + } else + xmlAttribute.ExpressionValue.AcceptVisitor(this, data); + return null; + } + + public override object TrackedVisitXmlElementExpression(XmlElementExpression xmlElementExpression, object data) + { + outputFormatter.PrintText("<"); + if (xmlElementExpression.NameIsExpression) { + outputFormatter.PrintToken(Tokens.XmlStartInlineVB); + outputFormatter.Space(); + xmlElementExpression.NameExpression.AcceptVisitor(this, data); + outputFormatter.Space(); + outputFormatter.PrintToken(Tokens.XmlEndInlineVB); + } else { + outputFormatter.PrintText(xmlElementExpression.XmlName); + } + foreach (XmlExpression attribute in xmlElementExpression.Attributes) { + outputFormatter.Space(); + attribute.AcceptVisitor(this, data); + } + if (xmlElementExpression.Children.Any()) { + outputFormatter.PrintText(">"); + foreach (INode node in xmlElementExpression.Children) { + node.AcceptVisitor(this, data); + } + outputFormatter.PrintText(""); + } else { + outputFormatter.Space(); + outputFormatter.PrintText("/>"); + } + return null; + } + + public override object TrackedVisitXmlMemberAccessExpression(XmlMemberAccessExpression xmlMemberAccessExpression, object data) + { + xmlMemberAccessExpression.TargetObject.AcceptVisitor(this, data); + switch (xmlMemberAccessExpression.AxisType) { + case XmlAxisType.Element: + outputFormatter.PrintToken(Tokens.Dot); + break; + case XmlAxisType.Attribute: + outputFormatter.PrintToken(Tokens.DotAt); + break; + case XmlAxisType.Descendents: + outputFormatter.PrintToken(Tokens.TripleDot); + break; + default: + throw new Exception("Invalid value for XmlAxisType"); + } + if (xmlMemberAccessExpression.IsXmlIdentifier) + outputFormatter.PrintText("<" + xmlMemberAccessExpression.Identifier + ">"); + else + outputFormatter.PrintIdentifier(xmlMemberAccessExpression.Identifier); + return null; + } } } diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs index e8c736833a..cdc93a674b 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs @@ -1273,7 +1273,7 @@ namespace ICSharpCode.NRefactory.Visitors { Debug.Assert(o != null); o.AcceptVisitor(this, data); } - return null; + return xmlElementExpression.AcceptChildren(this, data); } public virtual object VisitXmlEmbeddedExpression(XmlEmbeddedExpression xmlEmbeddedExpression, object data) { diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs index 4373dc0584..201beae949 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs @@ -2280,6 +2280,17 @@ namespace ICSharpCode.NRefactory.Visitors { else xmlElementExpression.Attributes[i] = o; } + for (int i = 0; i < xmlElementExpression.Children.Count; i++) { + INode o = xmlElementExpression.Children[i]; + Debug.Assert(o != null); + nodeStack.Push(o); + o.AcceptVisitor(this, data); + o = nodeStack.Pop(); + if (o == null) + xmlElementExpression.Children.RemoveAt(i--); + else + xmlElementExpression.Children[i] = o; + } return null; } diff --git a/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs b/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs index e011b41b04..9b028af7fe 100644 --- a/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs +++ b/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs @@ -31,7 +31,11 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter string StripWhitespace(string text) { - return text.Trim().Replace("\t", "").Replace("\r", "").Replace("\n", " ").Replace(" ", " "); + text = text.Trim().Replace("\t", "").Replace("\r", "").Replace("\n", " ").Replace(" ", " "); + while (text.Contains(" ")) { + text = text.Replace(" ", " "); + } + return text; } void TestTypeMember(string program) @@ -590,5 +594,78 @@ End Using"); " Return x * x\n" + "End Function"); } + + [Test] + public void XmlSimple() + { + TestExpression("\n" + + "\n" + + " \n" + + " />\n" + + ""); + } + + [Test] + public void XmlNested() + { + TestExpression(@" + + Shrimp Cocktail + Escargot + + + Filet Mignon + Garlic Potatoes + Broccoli + + + Chocolate Cheesecake + + "); + } + + [Test] + public void XmlDocument() + { + TestExpression(@" + + + Shrimp Cocktail + Escargot + + "); + } + + [Test] + public void XmlNestedWithExpressions() + { + TestExpression(@" + + + <%= From m In menu _ + Where m.Course = ""appetizer"" _ + Select <%= m.Food %> %> + + + <%= From m In menu _ + Where m.Course = ""main"" _ + Select <%= m.Food %> %> + + + <%= From m In menu _ + Where m.Course = ""dessert"" _ + Select <%= m.Food %> %> + + "); + } + + [Test] + public void XmlAccessExpressions() + { + TestExpression("xml.."); + TestExpression("xml..."); + TestExpression("xml...(2)"); + TestExpression("item.@name"); + } } }