From 5f4ab30f4dc40c1c857e5296fc0f4f1cabc76096 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 9 May 2010 16:05:56 +0000 Subject: [PATCH] fixed build (hopefully) git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@5801 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/VBNetBracketSearcher.cs | 246 ++++++++++++++++++ .../Src/Parser/VBNet/Experimental/Parser.cs | 46 ++-- .../VBNet/Experimental/ParserHelper.atg | 9 +- .../Base/Test/VBNetExpressionFinderTests.cs | 93 +++++++ 4 files changed, 358 insertions(+), 36 deletions(-) create mode 100644 src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetBracketSearcher.cs create mode 100644 src/Main/Base/Test/VBNetExpressionFinderTests.cs diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetBracketSearcher.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetBracketSearcher.cs new file mode 100644 index 0000000000..8f591bd352 --- /dev/null +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetBracketSearcher.cs @@ -0,0 +1,246 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +using ICSharpCode.Core; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.Parser; +using ICSharpCode.NRefactory.Parser.VB; +using ICSharpCode.SharpDevelop.Editor; + +namespace VBNetBinding +{ + public class VBNetBracketSearcher : IBracketSearcher + { + string openingBrackets = "([{"; + string closingBrackets = ")]}"; + + public BracketSearchResult SearchBracket(IDocument document, int offset) + { + if (offset > 0) { + char c = document.GetCharAt(offset - 1); + int index = openingBrackets.IndexOf(c); + int otherOffset = -1; + if (index > -1) + otherOffset = SearchBracketForward(document, offset, openingBrackets[index], closingBrackets[index]); + index = closingBrackets.IndexOf(c); + if (index > -1) + otherOffset = SearchBracketBackward(document, offset - 2, openingBrackets[index], closingBrackets[index]); + + if (otherOffset > -1) + return new BracketSearchResult(Math.Min(offset - 1, otherOffset), 1, Math.Max(offset - 1, otherOffset), 1); + + int length; + VBStatement statement; + + int startIndex = FindBeginStatementAroundOffset(document, offset, out statement, out length); + int endIndex = 0; + + if (statement != null) + endIndex = FindEndStatement(document, statement); + else { + endIndex = FindEndStatementAroundOffset(document, offset, out statement); + + if (statement != null) + startIndex = FindBeginStatement(document, statement, document.OffsetToPosition(endIndex), out length); + } + + if (startIndex > -1 && endIndex > -1) + return new BracketSearchResult(startIndex, length, endIndex, statement.EndStatement.Length); + } + + return null; + } + + #region bracket search + int SearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket) + { + bool inString = false; + char ch; + int brackets = -1; + for (int i = offset; i > 0; --i) { + ch = document.GetCharAt(i); + if (ch == openBracket && !inString) { + ++brackets; + if (brackets == 0) return i; + } else if (ch == closingBracket && !inString) { + --brackets; + } else if (ch == '"') { + inString = !inString; + } else if (ch == '\n') { + int lineStart = ScanLineStart(document, i); + if (lineStart >= 0) { // line could have a comment + inString = false; + for (int j = lineStart; j < i; ++j) { + ch = document.GetCharAt(j); + if (ch == '"') inString = !inString; + if (ch == '\'' && !inString) { + // comment found! + // Skip searching in the comment: + i = j; + break; + } + } + } + inString = false; + } + } + return -1; + } + + static int ScanLineStart(IDocument document, int offset) + { + bool hasComment = false; + for (int i = offset - 1; i > 0; --i) { + char ch = document.GetCharAt(i); + if (ch == '\n') { + if (!hasComment) return -1; + return i + 1; + } else if (ch == '\'') { + hasComment = true; + } + } + return 0; + } + + int SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket) + { + bool inString = false; + bool inComment = false; + int brackets = 1; + for (int i = offset; i < document.TextLength; ++i) { + char ch = document.GetCharAt(i); + if (ch == '\n') { + inString = false; + inComment = false; + } + if (inComment) continue; + if (ch == '"') inString = !inString; + if (inString) continue; + if (ch == '\'') { + inComment = true; + } else if (ch == openBracket) { + ++brackets; + } else if (ch == closingBracket) { + --brackets; + if (brackets == 0) return i; + } + } + return -1; + } + #endregion + + #region statement search + int FindBeginStatementAroundOffset(IDocument document, int offset, out VBStatement statement, out int length) + { + length = 0; + statement = null; + return -1; + } + + int FindEndStatementAroundOffset(IDocument document, int offset, out VBStatement statement) + { + IDocumentLine line = document.GetLineForOffset(offset); + + string interestingText = VBNetFormattingStrategy.TrimLine(line.Text).Trim(' ', '\t'); + + //LoggingService.Debug("text: '" + interestingText + "'"); + + foreach (VBStatement s in VBNetFormattingStrategy.Statements) { + Match match = Regex.Matches(interestingText, s.EndRegex, RegexOptions.Singleline | RegexOptions.IgnoreCase).OfType().FirstOrDefault(); + if (match != null) { + //LoggingService.DebugFormatted("Found end statement at offset {1}: {0}", s, offset); + statement = s; + int result = match.Index + (line.Length - line.Text.TrimStart(' ', '\t').Length) + line.Offset; + if (offset >= result && offset <= (result + match.Length)) + return result; + } + } + + statement = null; + return -1; + } + + int FindBeginStatement(IDocument document, VBStatement statement, Location endLocation, out int length) + { + ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, document.CreateReader()); + + Token currentToken = null; + Token prevToken = null; + + int lookFor = statement.StatementToken; + Stack tokens = new Stack(); + + if (statement.EndStatement == "Next") { + lookFor = Tokens.For; + } + + Token result = null; + + while ((currentToken = lexer.NextToken()).Kind != Tokens.EOF) { + if (prevToken == null) + prevToken = currentToken; + + if (VBNetFormattingStrategy.IsBlockStart(lexer, currentToken, prevToken)) + tokens.Push(currentToken); + if (VBNetFormattingStrategy.IsBlockEnd(currentToken, prevToken)) { + while (tokens.Count > 0 && !VBNetFormattingStrategy.IsMatchingEnd(tokens.Peek(), currentToken)) + tokens.Pop(); + if (tokens.Count > 0) { + Token t = tokens.Pop(); + if (currentToken.Location.Line == endLocation.Line) { + result = t; + break; + } + } + } + + prevToken = currentToken; + } + + if (result != null) { + + IDocumentLine line = document.GetLine(result.Location.Line); + string interestingText = VBNetFormattingStrategy.TrimLine(line.Text).Trim(' ', '\t'); + + //LoggingService.Debug("text2: '" + interestingText + "'"); + + Match matchResult = Regex.Match(interestingText, statement.StartRegex, RegexOptions.Singleline | RegexOptions.IgnoreCase); + + if (matchResult != null) { + length = matchResult.Value.TrimEnd(' ', '\t').Length; + int diff = line.Length - line.Text.TrimStart(' ', '\t').Length; + int start = diff + line.Offset; + if (IsDeclaration(result.Kind)) { + length += diff + matchResult.Index; + return start; + } + return matchResult.Index + start; + } + } + + length = 0; + + return -1; + } + + int FindEndStatement(IDocument document, VBStatement statement) + { + return -1; + } + #endregion + + bool IsDeclaration(int kind) + { + return kind == Tokens.Sub || kind == Tokens.Function || kind == Tokens.Operator || VBNetFormattingStrategy.IsDeclaration(kind); + } + } +} \ No newline at end of file diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Parser.cs b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Parser.cs index 3ad64234b6..2a02f38b8f 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Parser.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/Parser.cs @@ -106,7 +106,7 @@ public partial class Parser { while (la.kind == 124) { ImportsStatement(); } - while (la.kind == 1 || la.kind == 28) { + while (la.kind == 28) { AttributeBlock(); } while (StartOf(1)) { @@ -131,17 +131,20 @@ public partial class Parser { } void AttributeBlock() { - Attribute(); - while (la.kind == 1 || la.kind == 28) { - Attribute(); + Expect(28); + while (StartOf(3)) { + Get(); + } + Expect(27); + if (la.kind == 1) { + Get(); } - StatementTerminator(); } void NamespaceMemberDeclaration() { if (la.kind == 146) { NamespaceDeclaration(); - } else if (StartOf(3)) { + } else if (StartOf(4)) { TypeDeclaration(); } else SynErr(223); } @@ -154,20 +157,6 @@ public partial class Parser { } else SynErr(224); } - void Attribute() { - if (la.kind == 1) { - Get(); - } - Expect(28); - while (StartOf(4)) { - Get(); - } - Expect(27); - if (la.kind == 1) { - Get(); - } - } - void NamespaceDeclaration() { Expect(146); while (StartOf(2)) { @@ -183,7 +172,7 @@ public partial class Parser { } void TypeDeclaration() { - while (la.kind == 1 || la.kind == 28) { + while (la.kind == 28) { AttributeBlock(); } while (StartOf(5)) { @@ -219,7 +208,7 @@ public partial class Parser { } void SubOrFunctionDeclaration() { - while (la.kind == 1 || la.kind == 28) { + while (la.kind == 28) { AttributeBlock(); } while (StartOf(8)) { @@ -304,7 +293,7 @@ public partial class Parser { } void Parameter() { - while (la.kind == 1 || la.kind == 28) { + while (la.kind == 28) { AttributeBlock(); } while (StartOf(10)) { @@ -466,9 +455,6 @@ public partial class Parser { Get(); } else if (la.kind == 172) { Get(); - if (la.kind == 112) { - Get(); - } } else if (la.kind == 170) { Get(); } else SynErr(232); @@ -488,15 +474,15 @@ public partial class Parser { static readonly bool[,] set = { {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, - {x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, + {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, {x,x,T,T, T,T,T,T, T,T,T,x, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x}, - {x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x}, + {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, - {x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, T,T,T,x, T,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, + {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, T,T,T,x, T,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, T,T,T,x, T,x,T,x, T,T,x,x, x,x,x,x, x,x,x,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, - {x,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,x,T, T,T,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,T, x,x,T,x, x,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, T,x,x,x, x,x,T,x, x,x,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, T,x,T,x, x,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,T,T,x, x,x,x,x, x,x,x,x, T,T,x,x, x,x,x,T, x,x,x,x, x,x,x,x}, + {x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,x,T, T,T,T,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,T, x,x,T,x, x,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, T,x,x,x, x,x,T,x, x,x,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, T,x,T,x, x,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,T,T,x, x,x,x,x, x,x,x,x, T,T,x,x, x,x,x,T, x,x,x,x, x,x,x,x}, {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x}, {x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x}, {x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,x,T, T,T,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,x, x,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, T,x,x,x, x,x,T,x, x,x,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,T,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,T,T,x, x,x,x,x, x,x,x,x, T,T,x,x, x,x,x,T, x,x,x,x, x,x,x,x} diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ParserHelper.atg b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ParserHelper.atg index 6a3faacfd6..b5d1fc4da5 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ParserHelper.atg +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Experimental/ParserHelper.atg @@ -259,12 +259,9 @@ ImportsStatement = "Imports" { ANY } StatementTerminator . -AttributeBlock = - Attribute { Attribute } StatementTerminator -. -Attribute = - [ EOL ] "<" { ANY } ">" [ EOL ] +AttributeBlock = + "<" { ANY } ">" [ EOL ] . NamespaceMemberDeclaration = @@ -359,7 +356,7 @@ IdentifierForFieldDeclaration = AccessModifier = "Public" | "Friend" | - "Protected" [ "Friend" ] | + "Protected" | "Private" . diff --git a/src/Main/Base/Test/VBNetExpressionFinderTests.cs b/src/Main/Base/Test/VBNetExpressionFinderTests.cs new file mode 100644 index 0000000000..1f45c0a2f0 --- /dev/null +++ b/src/Main/Base/Test/VBNetExpressionFinderTests.cs @@ -0,0 +1,93 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Dom.VBNet; +using NUnit.Framework; + +namespace ICSharpCode.SharpDevelop.Tests +{ + [TestFixture] + public class VBNetExpressionFinderTests + { + #region init + VBNetExpressionFinder ef; + + [SetUp] + public void Init() + { + HostCallback.GetCurrentProjectContent = delegate { + return ParserService.CurrentProjectContent; + }; + + ef = new VBNetExpressionFinder(null); + } + #endregion + + #region helpers + void RunTestFull(string program, string lookingFor, string expectedExpression, ExpressionContext expectedContext, object expectedTag = null) + { + int offset = program.IndexOf(lookingFor); + if (offset < 0) Assert.Fail("lookingFor not found!"); + ExpressionResult result = ef.FindFullExpression(program, offset); + + Assert.AreEqual(expectedExpression, result.Expression); + Assert.AreEqual(expectedTag, result.Tag); + Assert.AreEqual(expectedExpression, ExtractRegion(program, result.Region)); + Assert.AreEqual(expectedContext, result.Context); + } + + void RunTest(string program, string lookingFor, string expectedExpression, ExpressionContext expectedContext, object expectedTag = null) + { + int offset = program.IndexOf(lookingFor); + if (offset < 0) Assert.Fail("lookingFor not found!"); + ExpressionResult result = ef.FindExpression(program, offset); + + Assert.AreEqual(expectedExpression, result.Expression); + Assert.AreEqual(expectedTag, result.Tag); + Assert.AreEqual(expectedExpression, ExtractRegion(program, result.Region)); + Assert.AreEqual(expectedContext, result.Context); + } + + static string ExtractRegion(string text, DomRegion region) + { + if (region.IsEmpty) + return null; + int start = GetOffsetByPosition(text, region.BeginLine, region.BeginColumn); + int end = GetOffsetByPosition(text, region.EndLine, region.EndColumn); + return text.Substring(start, end - start); + } + + static int GetOffsetByPosition(string text, int line, int column) + { + if (line < 1) + throw new ArgumentOutOfRangeException("line"); + if (line == 1) + return column - 1; + for (int i = 0; i < text.Length; i++) { + if (text[i] == '\n') { + if (--line == 1) { + return i + column; + } + } + } + throw new ArgumentOutOfRangeException("line"); + } + #endregion + + #region context1 + const string context1 = @" +Public Class Test + Public Sub New() + + End Sub +End Class +"; + #endregion + } +}