Browse Source

- fixed parser bugs

- fixed expression finder bugs
- implementation of some cc features

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6207 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
bcf917f92d
  1. 83
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/CompletionDataHelper.cs
  2. 41
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs
  3. 12
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionItemList.cs
  4. 2
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg
  5. 73
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  6. 2691
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs
  7. 8
      src/Libraries/NRefactory/Test/Lexer/VBNet/LiteralsTests.cs
  8. 10
      src/Main/Base/Test/VBExpressionFinderTests.cs
  9. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  10. 24
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

83
src/AddIns/BackendBindings/VBNetBinding/Project/Src/CompletionDataHelper.cs

@ -34,7 +34,6 @@ namespace ICSharpCode.VBNetBinding @@ -34,7 +34,6 @@ namespace ICSharpCode.VBNetBinding
List<ICompletionEntry> data = new List<ICompletionEntry>();
bool contextCompletion = false;
bool completingDotExpression = false;
IReturnType resolvedType = null;
@ -59,12 +58,15 @@ namespace ICSharpCode.VBNetBinding @@ -59,12 +58,15 @@ namespace ICSharpCode.VBNetBinding
var rr = resolver.Resolve(expressionResult, info, editor.Document.Text);
if (rr == null || !rr.IsValid) {
data = new NRefactoryResolver(LanguageProperties.VBNet)
.CtrlSpace(editor.Caret.Line, editor.Caret.Column, info, editor.Document.Text, expressionResult.Context, ((NRefactoryCompletionItemList)result).ContainsItemsFromAllNamespaces);
contextCompletion = true;
if (((BitArray)expressionResult.Tag)[Tokens.Identifier])
data = new NRefactoryResolver(LanguageProperties.VBNet)
.CtrlSpace(editor.Caret.Line, editor.Caret.Column, info, editor.Document.Text, expressionResult.Context,
((NRefactoryCompletionItemList)result).ContainsItemsFromAllNamespaces);
} else {
data = rr.GetCompletionData(info.CompilationUnit.ProjectContent, ((NRefactoryCompletionItemList)result).ContainsItemsFromAllNamespaces) ?? data;
data = rr.GetCompletionData(info.CompilationUnit.ProjectContent, ((NRefactoryCompletionItemList)result).ContainsItemsFromAllNamespaces)
?? new NRefactoryResolver(LanguageProperties.VBNet)
.CtrlSpace(editor.Caret.Line, editor.Caret.Column, info, editor.Document.Text,
expressionResult.Context, ((NRefactoryCompletionItemList)result).ContainsItemsFromAllNamespaces);
resolvedType = rr.ResolvedType;
}
@ -74,8 +76,6 @@ namespace ICSharpCode.VBNetBinding @@ -74,8 +76,6 @@ namespace ICSharpCode.VBNetBinding
if (expressionResult.Tag != null && (expressionResult.Context != ExpressionContext.Importable) && pressedKey != '.' && !completingDotExpression) {
AddVBNetKeywords(data, (BitArray)expressionResult.Tag);
if (!((BitArray)expressionResult.Tag)[Tokens.New] && expressionResult.Context == ExpressionContext.Type)
data.Add(new KeywordEntry("New"));
addedKeywords = true;
}
@ -85,10 +85,30 @@ namespace ICSharpCode.VBNetBinding @@ -85,10 +85,30 @@ namespace ICSharpCode.VBNetBinding
AddTemplates(editor, result);
string word = editor.GetWordBeforeCaret().Trim();
IClass c;
IClass c = GetCurrentClass(editor);
IMember m = GetCurrentMember(editor);
if (contextCompletion && pressedKey == ' ') {
HandleKeyword(ref result, info, resolvedType, word, c, m, editor, pressedKey);
AddSpecialItems(ref result, info, resolvedType, word, m, expressionResult, editor);
if (pressedKey == '\0') { // ctrl+space
char prevChar = editor.Caret.Offset > 0 ? editor.Document.GetCharAt(editor.Caret.Offset - 1) : '\0';
word = char.IsLetterOrDigit(prevChar) || prevChar == '_' ? editor.GetWordBeforeCaret() : "";
if (!string.IsNullOrWhiteSpace(word))
result.PreselectionLength = word.Length;
}
result.SortItems();
return result;
}
static void HandleKeyword(ref VBNetCompletionItemList result, ParseInformation info, IReturnType resolvedType, string word, IClass c, IMember m, ITextEditor editor, char pressedKey)
{
if (pressedKey == ' ') {
if (word.Equals("return", StringComparison.InvariantCultureIgnoreCase) && m != null) {
c = m.ReturnType != null ? m.ReturnType.GetUnderlyingClass() : null;
if (c != null) {
@ -101,40 +121,25 @@ namespace ICSharpCode.VBNetBinding @@ -101,40 +121,25 @@ namespace ICSharpCode.VBNetBinding
}
}
}
if (word.Equals("overrides", StringComparison.InvariantCultureIgnoreCase) && c != null) {
result = new OverrideCompletionItemProvider().GenerateCompletionList(editor).ToVBCCList();
}
}
c = GetCurrentClass(editor);
if (word.Equals("overrides", StringComparison.InvariantCultureIgnoreCase) && pressedKey == ' ' && c != null) {
return new OverrideCompletionItemProvider().GenerateCompletionList(editor).ToVBCCList();;
}
if (expressionResult.Context == ExpressionContext.Type && m != null && m.BodyRegion.IsInside(editor.Caret.Line, editor.Caret.Column)) {
result.Items.Add(
new DefaultCompletionItem("? =") {
Image = ClassBrowserIconService.GotoArrow,
Description = StringParser.Parse("${res:AddIns.VBNetBinding.CodeCompletion.QuestionmarkEqualsItem.Description}")
}
);
}
}
static void AddSpecialItems(ref VBNetCompletionItemList result, ParseInformation info, IReturnType resolvedType, string word, IMember m, ExpressionResult expressionResult, ITextEditor editor)
{
// if (expressionResult.Context == ExpressionContext.Type && m != null && m.BodyRegion.IsInside(editor.Caret.Line, editor.Caret.Column)) {
// result.Items.Add(new DefaultCompletionItem("? =") {
// Image = ClassBrowserIconService.GotoArrow,
// Description = StringParser.Parse("${res:AddIns.VBNetBinding.CodeCompletion.QuestionmarkEqualsItem.Description}")
// });
// }
if (resolvedType != null && AllowsDescendentAccess(resolvedType, info.CompilationUnit.ProjectContent))
result.Items.Add(new DefaultCompletionItem("..") { Image = ClassBrowserIconService.GotoArrow });
if (resolvedType != null && AllowsAttributeValueAccess(resolvedType, info.CompilationUnit.ProjectContent))
result.Items.Add(new DefaultCompletionItem("@") { Image = ClassBrowserIconService.GotoArrow });
if (pressedKey == '\0') { // ctrl+space
char prevChar = editor.Caret.Offset > 0 ? editor.Document.GetCharAt(editor.Caret.Offset - 1) : '\0';
word = char.IsLetterOrDigit(prevChar) || prevChar == '_' ? editor.GetWordBeforeCaret() : "";
if (!string.IsNullOrWhiteSpace(word))
result.PreselectionLength = word.Length;
}
result.SortItems();
return result;
}
static bool AllowsAttributeValueAccess(IReturnType resolvedType, IProjectContent content)

41
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs

@ -66,10 +66,21 @@ namespace ICSharpCode.VBNetBinding @@ -66,10 +66,21 @@ namespace ICSharpCode.VBNetBinding
TryDeclarationTypeInference(editor, editor.Document.GetLineForOffset(editor.Caret.Offset));
break;
case '.':
result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset);
string w = editor.GetWordBeforeCaret(); int index = w.IndexOf('.');
if (index > -1 && w.Length - index == 2)
index = editor.Caret.Offset - 2;
else
index = editor.Caret.Offset;
result = ef.FindExpression(editor.Document.Text, index);
LoggingService.Debug("CC: After dot, result=" + result + ", context=" + result.Context);
ShowCompletion(result, editor, ch);
return CodeCompletionKeyPressResult.Completed;
case '@':
if (editor.Caret.Offset > 0 && editor.Document.GetCharAt(editor.Caret.Offset - 1) == '.')
return CodeCompletionKeyPressResult.None;
goto default;
case ' ':
editor.Document.Insert(editor.Caret.Offset, " ");
result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset);
@ -84,16 +95,16 @@ namespace ICSharpCode.VBNetBinding @@ -84,16 +95,16 @@ namespace ICSharpCode.VBNetBinding
if (CodeCompletionOptions.CompleteWhenTyping) {
int cursor = editor.Caret.Offset;
char prevChar = cursor > 1 ? editor.Document.GetCharAt(cursor - 1) : ' ';
bool afterUnderscore = prevChar == '_';
if (afterUnderscore) {
cursor--;
prevChar = cursor > 1 ? editor.Document.GetCharAt(cursor - 1) : ' ';
}
char ppChar = cursor > 2 ? editor.Document.GetCharAt(cursor - 2) : ' ';
result = ef.FindExpression(editor.Document.Text, cursor);
if ((result.Context != ExpressionContext.IdentifierExpected && char.IsLetter(ch)) &&
(!char.IsLetterOrDigit(prevChar) && prevChar != '.')) {
if (prevChar == '@' && ppChar == '.')
return CodeCompletionKeyPressResult.None;
if (IsTypeCharacter(ch, prevChar))
return CodeCompletionKeyPressResult.None;
LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context);
ShowCompletion(result, editor, ch);
return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
@ -104,6 +115,24 @@ namespace ICSharpCode.VBNetBinding @@ -104,6 +115,24 @@ namespace ICSharpCode.VBNetBinding
return CodeCompletionKeyPressResult.None;
}
bool IsTypeCharacter(char ch, char prevChar)
{
ch = char.ToUpperInvariant(ch);
// char type character
if (ch == 'C' && prevChar == '"')
return true;
// start of hex or octal literal
if (prevChar == '&' && (ch == 'H' || ch == 'O'))
return true;
if (char.IsDigit(prevChar))
return true;
return false;
}
void ShowCompletion(ExpressionResult result, ITextEditor editor, char ch)
{

12
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionItemList.cs

@ -31,7 +31,19 @@ namespace ICSharpCode.VBNetBinding @@ -31,7 +31,19 @@ namespace ICSharpCode.VBNetBinding
if (key == '?' && string.IsNullOrWhiteSpace(Editor.Document.GetText(Window.StartOffset, Window.EndOffset - Window.StartOffset)))
return CompletionItemListKeyResult.NormalKey;
if (key == '@' && Window.StartOffset > 0 && Editor.Document.GetCharAt(Window.StartOffset - 1) == '.')
return CompletionItemListKeyResult.NormalKey;
return base.ProcessInput(key);
}
public override void Complete(CompletionContext context, ICompletionItem item)
{
base.Complete(context, item);
if (item.Text == "..") {
VBNetCompletionBinding.Instance.CtrlSpace(context.Editor);
}
}
}
}

2
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg

@ -1051,7 +1051,7 @@ RaiseEventStatement = @@ -1051,7 +1051,7 @@ RaiseEventStatement =
IfStatement =
"If" Expression
( "Then"
( Statement { ":" [Statement] } [ "Else" [Statement] { ":" [Statement] } ] EOL
( Statement { EXPECTEDCONFLICT(":") ":" [Statement] } [ EXPECTEDCONFLICT("Else") "Else" [Statement] { EXPECTEDCONFLICT(":") ":" [Statement] } ]
| MultilineIfRemainder
)
| MultilineIfRemainder

73
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs

@ -538,11 +538,11 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -538,11 +538,11 @@ namespace ICSharpCode.NRefactory.Parser.VB
digit += ch;
}
bool ishex = false;
bool isokt = false;
bool issingle = false;
bool isdouble = false;
bool isdecimal = false;
bool isHex = false;
bool isOct = false;
bool isSingle = false;
bool isDouble = false;
bool isDecimal = false;
if (ReaderPeek() == -1) {
if (ch == '&') {
@ -552,8 +552,8 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -552,8 +552,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
if (ch == '.') {
if (Char.IsDigit((char)ReaderPeek())) {
isdouble = true; // double is default
if (ishex || isokt) {
isDouble = true; // double is default
if (isHex || isOct) {
errors.Error(Line, Col, String.Format("No hexadecimal or oktadecimal floating point values allowed"));
}
while (ReaderPeek() != -1 && Char.IsDigit((char)ReaderPeek())){ // read decimal digits beyond the dot
@ -568,7 +568,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -568,7 +568,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
sb.Append(ch);
digit += Char.ToUpper(ch, CultureInfo.InvariantCulture);
}
ishex = true;
isHex = true;
} else if (ReaderPeek() != -1 && ch == '&' && PeekUpperChar() == 'O') {
const string okt = "01234567";
sb.Append((char)ReaderRead()); // skip 'O'
@ -577,7 +577,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -577,7 +577,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
sb.Append(ch);
digit += Char.ToUpper(ch, CultureInfo.InvariantCulture);
}
isokt = true;
isOct = true;
} else {
while (ReaderPeek() != -1 && Char.IsDigit((char)ReaderPeek())) {
ch = (char)ReaderRead();;
@ -591,7 +591,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -591,7 +591,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), 0, LiteralFormat.DecimalNumber);
}
if (ReaderPeek() != -1 && "%&SILU".IndexOf(PeekUpperChar()) != -1 || ishex || isokt) {
if (ReaderPeek() != -1 && "%&SILU".IndexOf(PeekUpperChar()) != -1 || isHex || isOct) {
bool unsigned = false;
if (ReaderPeek() != -1) {
ch = (char)ReaderPeek();
@ -609,7 +609,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -609,7 +609,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
}
try {
if (isokt) {
if (isOct) {
ReaderRead();
ulong number = 0L;
for (int i = 0; i < digit.Length; ++i) {
@ -638,26 +638,26 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -638,26 +638,26 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
}
}
LiteralFormat literalFormat = ishex ? LiteralFormat.HexadecimalNumber : LiteralFormat.DecimalNumber;
LiteralFormat literalFormat = isHex ? LiteralFormat.HexadecimalNumber : LiteralFormat.DecimalNumber;
if (ch == 'S') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt16.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int16.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
} else if (ch == '%' || ch == 'I') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt32.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
} else if (ch == '&' || ch == 'L') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt64.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
} else if (ishex) {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), literalFormat);
} else if (isHex) {
ulong number = UInt64.Parse(digit, NumberStyles.HexNumber);
if (number > uint.MaxValue) {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((long)number), literalFormat);
@ -668,14 +668,17 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -668,14 +668,17 @@ namespace ICSharpCode.NRefactory.Parser.VB
} catch (OverflowException ex) {
errors.Error(Line, Col, ex.Message);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), 0, LiteralFormat.None);
} catch (FormatException ex2) {
errors.Error(Line, Col, String.Format("{0} is not a parseable number", digit));
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), 0, LiteralFormat.None);
}
}
Token nextToken = null; // if we accedently read a 'dot'
if (!isdouble && ReaderPeek() == '.') { // read floating point number
Token nextToken = null; // if we accidently read a 'dot'
if (!isDouble && ReaderPeek() == '.') { // read floating point number
ReaderRead();
if (ReaderPeek() != -1 && Char.IsDigit((char)ReaderPeek())) {
isdouble = true; // double is default
if (ishex || isokt) {
isDouble = true; // double is default
if (isHex || isOct) {
errors.Error(Line, Col, String.Format("No hexadecimal or oktadecimal floating point values allowed"));
}
digit += '.';
@ -688,7 +691,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -688,7 +691,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
if (ReaderPeek() != -1 && PeekUpperChar() == 'E') { // read exponent
isdouble = true;
isDouble = true;
digit += (char)ReaderRead();
if (ReaderPeek() != -1 && (ReaderPeek() == '-' || ReaderPeek() == '+')) {
digit += (char)ReaderRead();
@ -703,46 +706,46 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -703,46 +706,46 @@ namespace ICSharpCode.NRefactory.Parser.VB
case 'R':
case '#':
ReaderRead();
isdouble = true;
isDouble = true;
break;
case 'D':
case '@':
ReaderRead();
isdecimal = true;
isDecimal = true;
break;
case 'F':
case '!':
ReaderRead();
issingle = true;
isSingle = true;
break;
}
}
try {
if (issingle) {
if (isSingle) {
return new Token(Tokens.LiteralSingle, x, y, sb.ToString(), Single.Parse(digit, CultureInfo.InvariantCulture), LiteralFormat.DecimalNumber);
}
if (isdecimal) {
if (isDecimal) {
return new Token(Tokens.LiteralDecimal, x, y, sb.ToString(), Decimal.Parse(digit, NumberStyles.Currency | NumberStyles.AllowExponent, CultureInfo.InvariantCulture), LiteralFormat.DecimalNumber);
}
if (isdouble) {
if (isDouble) {
return new Token(Tokens.LiteralDouble, x, y, sb.ToString(), Double.Parse(digit, CultureInfo.InvariantCulture), LiteralFormat.DecimalNumber);
}
} catch (FormatException) {
errors.Error(Line, Col, String.Format("{0} is not a parseable number", digit));
if (issingle)
if (isSingle)
return new Token(Tokens.LiteralSingle, x, y, sb.ToString(), 0f, LiteralFormat.DecimalNumber);
if (isdecimal)
if (isDecimal)
return new Token(Tokens.LiteralDecimal, x, y, sb.ToString(), 0m, LiteralFormat.DecimalNumber);
if (isdouble)
if (isDouble)
return new Token(Tokens.LiteralDouble, x, y, sb.ToString(), 0.0, LiteralFormat.DecimalNumber);
}
Token token;
try {
token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), ishex ? LiteralFormat.HexadecimalNumber : LiteralFormat.DecimalNumber);
token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), isHex ? LiteralFormat.HexadecimalNumber : LiteralFormat.DecimalNumber);
} catch (Exception) {
try {
token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number), ishex ? LiteralFormat.HexadecimalNumber : LiteralFormat.DecimalNumber);
token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, isHex ? NumberStyles.HexNumber : NumberStyles.Number), isHex ? LiteralFormat.HexadecimalNumber : LiteralFormat.DecimalNumber);
} catch (FormatException) {
errors.Error(Line, Col, String.Format("{0} is not a parseable number", digit));
// fallback, when nothing helps :)

2691
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

8
src/Libraries/NRefactory/Test/Lexer/VBNet/LiteralsTests.cs

@ -60,6 +60,14 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB @@ -60,6 +60,14 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
CheckToken("8581", Tokens.LiteralInteger, 8581);
}
[Test]
public void InvalidTypeCharacter()
{
// just check that we don't get exceptions:
GenerateLexer(new StringReader(".5s")).NextToken();
GenerateLexer(new StringReader(".5ul")).NextToken();
}
[Test]
public void TestHexadecimalInteger()
{

10
src/Main/Base/Test/VBExpressionFinderTests.cs

@ -196,6 +196,16 @@ End Class", "Te", ExpressionContext.Default); @@ -196,6 +196,16 @@ End Class", "Te", ExpressionContext.Default);
End Sub
End Class", "Test2", ExpressionContext.Default);
}
[Test]
public void FindExpressionAfterThen()
{
Find(@"Class MainClass
Sub Main()
If True Then Double|
End Sub
End Class", "Double", ExpressionContext.MethodBody);
}
#endregion
#region Context Tests

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -184,7 +184,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -184,7 +184,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
Expression expr = null;
if (language == NR.SupportedLanguage.VBNet) {
if (expression.Length == 0 || expression[0] == '.') {
if (expression.Length == 0 || expression[0] == '.' && (expression.Length > 1 && !char.IsDigit(expression[1]))) {
return WithResolve(expression, fileContent);
} else if ("global".Equals(expression, StringComparison.InvariantCultureIgnoreCase)) {
return new NamespaceResolveResult(null, null, "");

24
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

@ -61,25 +61,37 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -61,25 +61,37 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(text));
Token t = lexer.NextToken();
// put all tokens in front of targetPosition into the EF-Parser
while (t.EndLocation < targetPosition) {
p.InformToken(t);
t = lexer.NextToken();
}
// put current token into EF-Parser if it cannot be continued (is simple operator)
if (t.EndLocation == targetPosition && ((t.Kind <= Tokens.ColonAssign && t.Kind > Tokens.Identifier) || t.Kind == Tokens.EOL)) {
p.InformToken(t);
t = lexer.NextToken();
}
// make sure semantic actions are executed
p.Advance();
// remember current state, we'll use it to determine the context
var block = p.CurrentBlock;
ExpressionContext context = p.IsIdentifierExpected && !p.IsMissingModifier ? ExpressionContext.IdentifierExpected : GetContext(block);
BitArray expectedSet;
try {
expectedSet = p.GetExpectedSet();
} catch (InvalidOperationException) {
expectedSet = null;
}
// put current token into EF-Parser
if (t.Location < targetPosition) {
p.InformToken(t);
p.Advance();
}
if (p.Errors.Any()) {
@ -87,18 +99,10 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -87,18 +99,10 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
LoggingService.Warn("not expected: " + e);
}
BitArray expectedSet;
try {
expectedSet = p.GetExpectedSet();
} catch (InvalidOperationException) {
expectedSet = null;
}
if (p.NextTokenIsPotentialStartOfExpression)
return new ExpressionResult("", new DomRegion(targetPosition.Line, targetPosition.Column), context, expectedSet);
int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart);
int lastExpressionStartOffset = LocationToOffset(p.CurrentBlock.lastExpressionStart);
if (lastExpressionStartOffset < 0)
return new ExpressionResult("", new DomRegion(targetPosition.Line, targetPosition.Column), context, expectedSet);

Loading…
Cancel
Save