diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/Token.cs b/src/Libraries/NRefactory/Project/Src/Lexer/Token.cs index 7ee0680bc7..7dbc809c78 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/Token.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/Token.cs @@ -64,6 +64,10 @@ namespace ICSharpCode.NRefactory.Parser { } + public Token(int kind, Location startLocation, Location endLocation) : this(kind, startLocation, endLocation, "", null, LiteralFormat.None) + { + } + public Token(int kind, int col, int line, string val) { this.kind = kind; diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs index 87f4e39fda..b5ff0eaf8e 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs @@ -118,19 +118,17 @@ namespace ICSharpCode.NRefactory.Parser.VB if (ReaderPeek() == '/') { ReaderRead(); info.inXmlCloseTag = true; - return new Token(Tokens.XmlOpenEndTag, x, y); + return new Token(Tokens.XmlOpenEndTag, new Location(x, y), new Location(Col, Line)); } if (ReaderPeek() == '%' && ReaderPeek(1) == '=') { inXmlMode = false; ReaderRead(); ReaderRead(); - return new Token(Tokens.XmlStartInlineVB, x, y); + return new Token(Tokens.XmlStartInlineVB, new Location(x, y), new Location(Col, Line)); } if (ReaderPeek() == '?') { ReaderRead(); Token t = ReadXmlProcessingInstruction(x, y); info.wasProcessingInstruction = true; - ReaderRead(); - ReaderRead(); return t; } if (ReaderPeek() == '!') { @@ -147,7 +145,7 @@ namespace ICSharpCode.NRefactory.Parser.VB ReaderRead(); info.inXmlTag = false; info.level--; - return new Token(Tokens.XmlCloseTagEmptyElement, x, y); + return new Token(Tokens.XmlCloseTagEmptyElement, new Location(x, y), new Location(Col, Line)); } break; case '>': @@ -338,7 +336,7 @@ namespace ICSharpCode.NRefactory.Parser.VB int y = Line; inXmlMode = true; ReaderRead(); - return new Token(Tokens.XmlEndInlineVB, x, y); + return new Token(Tokens.XmlEndInlineVB, new Location(x, y), new Location(Col, Line)); } #endregion if (ch == '<' && (ef.NextTokenIsPotentialStartOfXmlMode || ef.NextTokenIsStartOfImportsOrAccessExpression)) { @@ -350,12 +348,12 @@ namespace ICSharpCode.NRefactory.Parser.VB if (ReaderPeek() == '/') { ReaderRead(); info.inXmlCloseTag = true; - return new Token(Tokens.XmlOpenEndTag, x, y); + return new Token(Tokens.XmlOpenEndTag, new Location(x, y), new Location(Col, Line)); } if (ReaderPeek() == '%' && ReaderPeek(1) == '=') { // TODO : suspend xml mode tracking ReaderRead(); ReaderRead(); - return new Token(Tokens.XmlStartInlineVB, x, y); + return new Token(Tokens.XmlStartInlineVB, new Location(x, y), new Location(Col, Line)); } if (ReaderPeek() == '!') { ReaderRead(); @@ -367,8 +365,6 @@ namespace ICSharpCode.NRefactory.Parser.VB ReaderRead(); Token t = ReadXmlProcessingInstruction(x, y); info.wasProcessingInstruction = true; - ReaderRead(); - ReaderRead(); return t; } info.inXmlTag = true; @@ -399,7 +395,9 @@ namespace ICSharpCode.NRefactory.Parser.VB sb.Append((char)nextChar); } - return new Token(Tokens.XmlProcessingInstruction, x, y, sb.ToString()); + ReaderSkip("?>".Length); + + return new Token(Tokens.XmlProcessingInstruction, new Location(x, y), new Location(Col, Line), sb.ToString(), null, LiteralFormat.None); } Token ReadXmlCommentOrCData(int x, int y) diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs index 28012b3030..4bd30fbf82 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs @@ -3692,6 +3692,9 @@ exprs); XmlElement( #line 1781 "VBNET.ATG" out currentExpression); + +#line 1781 "VBNET.ATG" + exprs.Add(currentExpression); while (StartOf(32)) { XmlContentExpression( #line 1781 "VBNET.ATG" @@ -3702,6 +3705,9 @@ exprs); XmlElement( #line 1783 "VBNET.ATG" out currentExpression); + +#line 1783 "VBNET.ATG" + exprs.Add(currentExpression); while (StartOf(32)) { XmlContentExpression( #line 1783 "VBNET.ATG" @@ -4612,6 +4618,9 @@ out XmlExpression expr) { #line 1817 "VBNET.ATG" XmlElementExpression el = new XmlElementExpression(); Expect(10); + +#line 1820 "VBNET.ATG" + el.StartLocation = t.Location; if (la.kind == 12) { lexer.NextToken(); @@ -4637,6 +4646,9 @@ el.Attributes); } if (la.kind == 14) { lexer.NextToken(); + +#line 1824 "VBNET.ATG" + el.EndLocation = t.EndLocation; } else if (la.kind == 11) { lexer.NextToken(); while (StartOf(37)) { @@ -4655,6 +4667,9 @@ out child); lexer.NextToken(); } Expect(11); + +#line 1824 "VBNET.ATG" + el.EndLocation = t.EndLocation; } else SynErr(288); #line 1826 "VBNET.ATG" diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG index 34f2a2a955..495bb9136f 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG @@ -1778,9 +1778,9 @@ XmlLiteralExpression .) = ( - XmlContentExpression { XmlContentExpression } [ XmlElement { XmlContentExpression } ] + XmlContentExpression { XmlContentExpression } [ XmlElement (. exprs.Add(currentExpression); .) { XmlContentExpression } ] | - XmlElement { XmlContentExpression } + XmlElement (. exprs.Add(currentExpression); .) { XmlContentExpression } ) . @@ -1817,11 +1817,11 @@ XmlElement (. XmlElementExpression el = new XmlElementExpression(); .) = ( - XmlOpenTag + XmlOpenTag (. el.StartLocation = t.Location; .) ( XmlStartInlineVB (. Expression innerExpression; .) Expr XmlEndInlineVB (. el.NameExpression = new XmlEmbeddedExpression() { InlineVBExpression = innerExpression }; .) | Identifier (. el.XmlName = t.val; .) ) { XmlAttribute } - ( XmlCloseTagEmptyElement | XmlCloseTag { (. XmlExpression child; .) XmlNestedContent (. el.Children.Add(child); .) } XmlOpenEndTag { ANY } XmlCloseTag ) + ( XmlCloseTagEmptyElement (. el.EndLocation = t.EndLocation; .) | XmlCloseTag { (. XmlExpression child; .) XmlNestedContent (. el.Children.Add(child); .) } XmlOpenEndTag { ANY } XmlCloseTag (. el.EndLocation = t.EndLocation; .) ) ) (. expr = el; .) . diff --git a/src/Libraries/NRefactory/Test/Parser/Expressions/XmlLiteralExpressionTests.cs b/src/Libraries/NRefactory/Test/Parser/Expressions/XmlLiteralExpressionTests.cs index dc45ad8fad..39faf7d3bd 100644 --- a/src/Libraries/NRefactory/Test/Parser/Expressions/XmlLiteralExpressionTests.cs +++ b/src/Libraries/NRefactory/Test/Parser/Expressions/XmlLiteralExpressionTests.cs @@ -35,6 +35,47 @@ namespace ICSharpCode.NRefactory.Tests.Ast Assert.AreEqual(new Location(1,1), content.StartLocation); Assert.AreEqual(new Location(14,1), content.EndLocation); } + + [Test] + public void VBNetSimplePreprocessingInstructionTest() + { + XmlLiteralExpression xle = ParseUtilVBNet.ParseExpression(""); + Assert.IsNotEmpty(xle.Expressions); + Assert.IsTrue(xle.Expressions[0] is XmlContentExpression); + XmlContentExpression content = xle.Expressions[0] as XmlContentExpression; + Assert.AreEqual(XmlContentType.ProcessingInstruction, content.Type); + Assert.AreEqual("xml version='1.0'", content.Content); + Assert.AreEqual(new Location(1,1), content.StartLocation); + Assert.AreEqual(new Location(22,1), content.EndLocation); + } + + [Test] + public void VBNetSimpleCDataTest() + { + XmlLiteralExpression xle = ParseUtilVBNet.ParseExpression(" ]]>"); + Assert.IsNotEmpty(xle.Expressions); + Assert.IsTrue(xle.Expressions[0] is XmlContentExpression); + XmlContentExpression content = xle.Expressions[0] as XmlContentExpression; + Assert.AreEqual(XmlContentType.CData, content.Type); + Assert.AreEqual(" ", content.Content); + Assert.AreEqual(new Location(1,1), content.StartLocation); + Assert.AreEqual(new Location(29,1), content.EndLocation); + } + + [Test] + public void VBNetSimpleEmptyElementTest() + { + XmlLiteralExpression xle = ParseUtilVBNet.ParseExpression(""); + Assert.IsNotEmpty(xle.Expressions); + Assert.IsTrue(xle.Expressions[0] is XmlElementExpression); + XmlElementExpression element = xle.Expressions[0] as XmlElementExpression; + Assert.IsFalse(element.NameIsExpression); + Assert.AreEqual("Test", element.XmlName); + Assert.IsEmpty(element.Attributes); + Assert.IsEmpty(element.Children); + Assert.AreEqual(new Location(1,1), element.StartLocation); + Assert.AreEqual(new Location(9,1), element.EndLocation); + } #endregion } }