diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs index af49ce29e7..bab6219940 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs @@ -112,6 +112,12 @@ namespace ICSharpCode.NRefactory.Parser.VB get { return stack.Any() ? stack.Peek() : Block.Default; } } + public bool IsIdentifierExpected { + get { + return stack.Take(2).Any(c => c.context == Context.IdentifierExpected); + } + } + public bool NextTokenIsPotentialStartOfExpression { get { return nextTokenIsPotentialStartOfExpression; } } diff --git a/src/Main/Base/Test/VBExpressionFinderTests.cs b/src/Main/Base/Test/VBExpressionFinderTests.cs index 8edaab53d9..0ca12d0270 100644 --- a/src/Main/Base/Test/VBExpressionFinderTests.cs +++ b/src/Main/Base/Test/VBExpressionFinderTests.cs @@ -83,19 +83,19 @@ End Class [Test] public void FindSimple() { - Find(program2, "sole", 0,"Console", ExpressionContext.Default); + Find(program2, "sole", 0,"Con", ExpressionContext.Default); } [Test] public void FindSimple2() { - Find(program2, "Wri", 0, "Console.WriteLine", ExpressionContext.Default); + Find(program2, "Wri", 0, "Console.", ExpressionContext.Default); } [Test] public void FindSimple3() { - Find(program3, "WriteLine", "WriteLine".Length, "Console.WriteLine", ExpressionContext.MethodBody); + Find(program3, "WriteLine", "WriteLine".Length, "Console.WriteLine", ExpressionContext.Default); } [Test] @@ -103,6 +103,12 @@ End Class { Find(program2, "WriteLine", "WriteLine(".Length, "", ExpressionContext.Default); } + + [Test] + public void ForEachLoop() + { + Find(program1, "loopVarName", 4, "loop", ExpressionContext.Default); + } #endregion #region FindFull @@ -173,14 +179,14 @@ End Class"; ".Length + offset).Expression); } - void OldTestFind(string expr, int offset) + void OldTestFind(string expr, string expected, int offset) { string body = @"Class Test Sub A Dim x = abc + {0} End Sub End Class"; - Assert.AreEqual(expr, ef.FindExpression(string.Format(body, expr), @"Class Test + Assert.AreEqual(expected, ef.FindExpression(string.Format(body, expr), @"Class Test Sub A Dim x = abc + ".Length + offset).Expression); } @@ -211,10 +217,16 @@ End Class"; OldTest("abc.Method().Method(5, a.b, 5 + a)", 16); } - [Test, Ignore] + [Test] public void PlusExpression() { - OldTestFind("def", 2); + OldTestFind("def", "de", 2); + } + + [Test] + public void PlusExpression2() + { + OldTestFind("def", "", 0); } #endregion #endregion diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs index 0ec4ee3c05..7c3bf873d1 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs @@ -59,38 +59,29 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet ExpressionFinder p = new ExpressionFinder(); lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(text)); Token t; + do { t = lexer.NextToken(); + if (t.Location >= targetPosition) + break; p.InformToken(t); - } while (t.Location < targetPosition); + } while (t.EndLocation < targetPosition); + + var block = p.CurrentBlock; + + p.Advance(); if (p.NextTokenIsPotentialStartOfExpression) return new ExpressionResult("", GetContext(p.CurrentBlock)); - Block block = p.CurrentBlock; + int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart); - var expressionDelimiters = new[] { Tokens.EOL, Tokens.Colon, Tokens.Dot, Tokens.TripleDot, Tokens.DotAt, Tokens.OpenParenthesis }; + ExpressionContext context = p.IsIdentifierExpected ? ExpressionContext.IdentifierExpected : GetContext(block); - int tokenOffset; - if (t == null || t.Kind == Tokens.EOF) - tokenOffset = text.Length; - else - tokenOffset = expressionDelimiters.Contains(t.Kind) - ? LocationToOffset(t.Location) - : LocationToOffset(t.EndLocation); - - int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart); - if (lastExpressionStartOffset >= 0) { - if (offset < tokenOffset) { - // offset is in front of this token - return MakeResult(text, lastExpressionStartOffset, tokenOffset, GetContext(block)); - } else { - // offset is IN this token - return MakeResult(text, lastExpressionStartOffset, offset, GetContext(block)); - } - } else { - return new ExpressionResult(null, GetContext(block)); - } + if (lastExpressionStartOffset < 0) + return new ExpressionResult(null, context); + + return MakeResult(text, lastExpressionStartOffset, offset, context); } ExpressionResult MakeResult(string text, int startOffset, int endOffset, ExpressionContext context)