Browse Source

- reorganised some files of the VB Lexer

- fixed a bug in the ILC detection
- started with CC implementation based on new API

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6088 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
4c47339173
  1. 51
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCodeCompletionDataProvider.cs
  2. 161
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs
  3. 8
      src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.addin
  4. 1
      src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.csproj
  5. 8
      src/Libraries/NRefactory/Project/NRefactory.csproj
  6. 8
      src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs
  7. 4
      src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs
  8. 2
      src/Libraries/NRefactory/Project/Src/Lexer/LexerMemento.cs
  9. 24
      src/Libraries/NRefactory/Project/Src/Lexer/SavepointEventArgs.cs
  10. 55
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Block.cs
  11. 59
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs
  12. 25
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinderState.cs
  13. 26
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Extensions.cs
  14. 18
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  15. 2
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBLexerMemento.cs
  16. 2
      src/Libraries/NRefactory/Project/Src/ParserFactory.cs
  17. 46
      src/Libraries/NRefactory/Test/Lexer/VBNet/ImplicitLineContinuationTests.cs
  18. 9
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  19. 11
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

51
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCodeCompletionDataProvider.cs

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision: 6077 $</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
namespace ICSharpCode.VBNetBinding
{
public class VBNetCodeCompletionDataProvider : NRefactoryCtrlSpaceCompletionItemProvider
{
ExpressionResult result;
public VBNetCodeCompletionDataProvider(ExpressionResult result)
: base(LanguageProperties.VBNet, result.Context)
{
this.result = result;
}
protected override List<ICompletionEntry> CtrlSpace(ITextEditor editor, ExpressionContext context)
{
var list = base.CtrlSpace(editor, context);
BitArray expectedSet = result.Tag as BitArray;
if (expectedSet != null)
AddVBNetKeywords(list, expectedSet);
return list;
}
static void AddVBNetKeywords(List<ICompletionEntry> ar, BitArray keywords)
{
for (int i = 0; i < keywords.Length; i++) {
if (keywords[i] && i >= Tokens.AddHandler) {
ar.Add(new KeywordEntry(Tokens.GetTokenString(i)));
}
}
}
}
}

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

@ -6,7 +6,16 @@ @@ -6,7 +6,16 @@
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Dom.VBNet;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
@ -14,34 +23,176 @@ namespace ICSharpCode.VBNetBinding @@ -14,34 +23,176 @@ namespace ICSharpCode.VBNetBinding
{
public class VBNetCompletionBinding : ICodeCompletionBinding
{
static VBNetCompletionBinding instance;
public static VBNetCompletionBinding Instance {
get {
if (instance == null)
instance = new VBNetCompletionBinding();
return instance;
}
}
public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
{
if (IsInComment(editor))
return CodeCompletionKeyPressResult.None;
switch (ch) {
case '\n':
break;
case ' ':
if (CodeCompletionOptions.KeywordCompletionEnabled) {
string word = editor.GetWordBeforeCaret();
if (!string.IsNullOrEmpty(word)) {
if (HandleKeyword(editor, word))
return CodeCompletionKeyPressResult.Completed;
var list = HandleKeyword(editor, word);
editor.ShowCompletionWindow(list);
return CodeCompletionKeyPressResult.Completed;
}
}
break;
default:
if (CodeCompletionOptions.CompleteWhenTyping) {
if (editor.SelectionLength > 0) {
// allow code completion when overwriting an identifier
int endOffset = editor.SelectionStart + editor.SelectionLength;
// but block code completion when overwriting only part of an identifier
if (endOffset < editor.Document.TextLength && char.IsLetterOrDigit(editor.Document.GetCharAt(endOffset)))
return CodeCompletionKeyPressResult.None;
editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
}
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) : ' ';
}
if (!char.IsLetterOrDigit(prevChar) && prevChar != '.') {
VBNetExpressionFinder ef = new VBNetExpressionFinder(ParserService.GetParseInformation(editor.FileName));
ExpressionResult result = ef.FindExpression(editor.Document.Text, cursor);
LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context);
if (result.Context != ExpressionContext.IdentifierExpected) {
var provider = new VBNetCodeCompletionDataProvider(result);
provider.ShowTemplates = true;
provider.AllowCompleteExistingExpression = afterUnderscore;
provider.ShowCompletion(editor);
return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
}
}
}
break;
}
return CodeCompletionKeyPressResult.None;
}
bool IsInComment(ITextEditor editor)
{
ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, editor.Document.CreateReader());
Token t = lexer.NextToken();
bool inXml = false;
while (t.Location < editor.Caret.Position) {
t = lexer.NextToken();
if (inXml && (t.Kind != Tokens.Identifier && t.Kind != Tokens.LiteralString && !(t.Kind > Tokens.LiteralDate && t.Kind < Tokens.Colon))) {
inXml = false;
continue;
}
if (t.Kind > Tokens.LiteralDate && t.Kind < Tokens.Assign)
inXml = true;
}
if (inXml) {
return true;
} else {
string lineText = editor.Document.GetLine(t.Location.Line).Text;
bool inString = false;
bool inComment = false;
for (int i = 0; i < lineText.Length; i++) {
char ch = lineText[i];
if (!inComment && ch == '"')
inString = !inString;
if (!inString && ch == '\'')
inComment = true;
}
return inComment;
}
}
public bool CtrlSpace(ITextEditor editor)
{
if (IsInComment(editor))
return false;
if (editor.SelectionLength > 0) {
// allow code completion when overwriting an identifier
int endOffset = editor.SelectionStart + editor.SelectionLength;
// but block code completion when overwriting only part of an identifier
if (endOffset < editor.Document.TextLength && char.IsLetterOrDigit(editor.Document.GetCharAt(endOffset)))
return false;
editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
}
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) : ' ';
}
if (!char.IsLetterOrDigit(prevChar) && prevChar != '.') {
VBNetExpressionFinder ef = new VBNetExpressionFinder(ParserService.GetParseInformation(editor.FileName));
ExpressionResult result = ef.FindExpression(editor.Document.Text, cursor);
LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context);
if (result.Context != ExpressionContext.IdentifierExpected) {
var provider = new VBNetCodeCompletionDataProvider(result);
provider.ShowTemplates = true;
provider.AllowCompleteExistingExpression = afterUnderscore;
provider.ShowCompletion(editor);
return true;
}
}
return false;
}
bool HandleKeyword(ITextEditor editor, string word)
sealed class GlobalCompletionItemProvider : CodeCompletionItemProvider
{
return false;
public override ExpressionResult GetExpression(ITextEditor editor)
{
return new ExpressionResult("Global", ExpressionContext.Importable);
}
}
ICompletionItemList HandleKeyword(ITextEditor editor, string word)
{
DefaultCompletionItemList list = new DefaultCompletionItemList();
switch (word.ToLowerInvariant()) {
case "option":
return new TextCompletionItemProvider(
"Explicit On", "Explicit Off",
"Strict On", "Strict Off",
"Compare Binary", "Compare Text",
"Infer On", "Infer Off"
).GenerateCompletionList(editor);
case "imports":
return new GlobalCompletionItemProvider().GenerateCompletionList(editor);
break;
}
return list;
}
}
}

8
src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.addin

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<AddIn name = "VB Binding"
author = "Mike Krueger, Markus Palme"
<AddIn name = "VB .NET Binding"
author = "Siegfried Pammer"
copyright = "prj:///doc/copyright.txt"
description = "Backing binding for VB.NET"
description = "Backend binding for VB.NET"
addInManagerHidden = "preinstalled">
<Manifest>
@ -96,7 +96,7 @@ @@ -96,7 +96,7 @@
</Path>
<Path name = "/AddIns/DefaultTextEditor/CodeCompletion">
<CodeCompletionBinding id = "VBNet" extensions = ".vb" class = "VBNetBinding.VBNetCompletionBinding"/>
<CodeCompletionBinding id = "VBNet" extensions = ".vb" class = "ICSharpCode.VBNetBinding.VBNetCompletionBinding"/>
</Path>
<Path name="/SharpDevelop/Workbench/LanguageBindings">

1
src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.csproj

@ -54,6 +54,7 @@ @@ -54,6 +54,7 @@
<Compile Include="Src\Extensions.cs" />
<Compile Include="Src\FormattingStrategy\VBStatement.cs" />
<Compile Include="Src\VBNetBracketSearcher.cs" />
<Compile Include="Src\VBNetCodeCompletionDataProvider.cs" />
<Compile Include="Src\VBNetCompletionBindingOld.cs" />
<Compile Include="Src\VBNetLanguageBinding.cs" />
<Compile Include="Src\VBNetProjectBinding.cs" />

8
src/Libraries/NRefactory/Project/NRefactory.csproj

@ -61,8 +61,12 @@ @@ -61,8 +61,12 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Src\Lexer\LATextReader.cs" />
<Compile Include="Src\Lexer\AbstractLexerState.cs" />
<Compile Include="Src\Lexer\LexerMemento.cs" />
<Compile Include="Src\Lexer\SavepointEventArgs.cs" />
<Compile Include="Src\Lexer\VBNet\Block.cs" />
<Compile Include="Src\Lexer\VBNet\ExpressionFinder.cs" />
<Compile Include="Src\Lexer\VBNet\ExpressionFinderState.cs" />
<Compile Include="Src\Lexer\VBNet\Extensions.cs" />
<Compile Include="Src\Lexer\VBNet\Parser.cs">
<DependentUpon>ExpressionFinder.atg</DependentUpon>
</Compile>
@ -91,7 +95,7 @@ @@ -91,7 +95,7 @@
<Compile Include="..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Src\Lexer\VBNet\VBLexerState.cs" />
<Compile Include="Src\Lexer\VBNet\VBLexerMemento.cs" />
<Compile Include="Src\Lexer\VBNet\XmlModeInfo.cs" />
<Compile Include="Src\OperatorPrecedence.cs" />
<Compile Include="Src\Parser\CSharp\CSharpParser.cs" />

8
src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs

@ -196,7 +196,7 @@ namespace ICSharpCode.NRefactory.Parser @@ -196,7 +196,7 @@ namespace ICSharpCode.NRefactory.Parser
this.reader = new LATextReader(reader);
}
protected AbstractLexer(TextReader reader, AbstractLexerState state)
protected AbstractLexer(TextReader reader, LexerMemento state)
: this(reader)
{
SetInitialLocation(new Location(state.Column, state.Line));
@ -368,16 +368,16 @@ namespace ICSharpCode.NRefactory.Parser @@ -368,16 +368,16 @@ namespace ICSharpCode.NRefactory.Parser
/// </summary>
public abstract void SkipCurrentBlock(int targetToken);
public event EventHandler SavepointReached;
public event EventHandler<SavepointEventArgs> SavepointReached;
protected virtual void OnSavepointReached(EventArgs e)
protected virtual void OnSavepointReached(SavepointEventArgs e)
{
if (SavepointReached != null) {
SavepointReached(this, e);
}
}
public virtual AbstractLexerState Export()
public virtual LexerMemento Export()
{
throw new NotSupportedException();
}

4
src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs

@ -111,12 +111,12 @@ namespace ICSharpCode.NRefactory.Parser @@ -111,12 +111,12 @@ namespace ICSharpCode.NRefactory.Parser
/// Used to export the current state of the lexer. The exported state should be
/// complete, so that it is possible to reset the lexer to a previous state completely.
/// </summary>
AbstractLexerState Export();
LexerMemento Export();
/// <summary>
/// Is fired by the lexer as soon as a savepoint is reached.
/// The Export-method can be used to retrieve the current state.
/// </summary>
event EventHandler SavepointReached;
event EventHandler<SavepointEventArgs> SavepointReached;
}
}

2
src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexerState.cs → src/Libraries/NRefactory/Project/Src/Lexer/LexerMemento.cs

@ -8,7 +8,7 @@ using System; @@ -8,7 +8,7 @@ using System;
namespace ICSharpCode.NRefactory.Parser
{
public abstract class AbstractLexerState
public abstract class LexerMemento
{
public int Line { get; set; }
public int Column { get; set; }

24
src/Libraries/NRefactory/Project/Src/Lexer/SavepointEventArgs.cs

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 6084 $</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.Parser
{
public class SavepointEventArgs : EventArgs
{
public Location SavepointLocation { get; private set; }
public LexerMemento State { get; private set; }
public SavepointEventArgs(Location savepointLocation, LexerMemento state)
{
this.SavepointLocation = savepointLocation;
this.State = state;
}
}
}

55
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Block.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com" />
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.NRefactory.Parser.VB
{
public enum Context
{
Global,
Type,
Member,
IdentifierExpected,
Body,
Xml,
Attribute,
Query,
Expression,
Debug,
Default
}
public class Block : ICloneable
{
public static readonly Block Default = new Block() {
context = Context.Global,
lastExpressionStart = Location.Empty
};
public Context context;
public Location lastExpressionStart;
public bool isClosed;
public override string ToString()
{
return string.Format("[Block Context={0}, LastExpressionStart={1}, IsClosed={2}]", context, lastExpressionStart, isClosed);
}
public object Clone()
{
return new Block() {
context = this.context,
lastExpressionStart = this.lastExpressionStart,
isClosed = this.isClosed
};
}
}
}

59
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs

@ -118,6 +118,13 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -118,6 +118,13 @@ namespace ICSharpCode.NRefactory.Parser.VB
}
}
public bool InContext(Context expected)
{
return stack
.SkipWhile(f => f.context == Context.Expression)
.IsElement(fx => fx.context == expected);
}
public bool NextTokenIsPotentialStartOfExpression {
get { return nextTokenIsPotentialStartOfExpression; }
}
@ -152,56 +159,4 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -152,56 +159,4 @@ namespace ICSharpCode.NRefactory.Parser.VB
};
}
}
public class ExpressionFinderState
{
public bool WasQualifierTokenAtStart { get; set; }
public bool NextTokenIsPotentialStartOfExpression { get; set; }
public bool ReadXmlIdentifier { get; set; }
public bool NextTokenIsStartOfImportsOrAccessExpression { get; set; }
public Stack<int> StateStack { get; set; }
public Stack<Block> BlockStack { get; set; }
public int CurrentState { get; set; }
}
public enum Context
{
Global,
Type,
Member,
IdentifierExpected,
Body,
Xml,
Attribute,
Query,
Expression,
Debug,
Default
}
public class Block : ICloneable
{
public static readonly Block Default = new Block() {
context = Context.Global,
lastExpressionStart = Location.Empty
};
public Context context;
public Location lastExpressionStart;
public bool isClosed;
public override string ToString()
{
return string.Format("[Block Context={0}, LastExpressionStart={1}, IsClosed={2}]", context, lastExpressionStart, isClosed);
}
public object Clone()
{
return new Block() {
context = this.context,
lastExpressionStart = this.lastExpressionStart,
isClosed = this.isClosed
};
}
}
}

25
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinderState.cs

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com" />
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.NRefactory.Parser.VB
{
public class ExpressionFinderState
{
public bool WasQualifierTokenAtStart { get; set; }
public bool NextTokenIsPotentialStartOfExpression { get; set; }
public bool ReadXmlIdentifier { get; set; }
public bool NextTokenIsStartOfImportsOrAccessExpression { get; set; }
public Stack<int> StateStack { get; set; }
public Stack<Block> BlockStack { get; set; }
public int CurrentState { get; set; }
}
}

26
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Extensions.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com" />
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.NRefactory.Parser.VB
{
public static class Extensions
{
public static bool IsElement<T>(this IEnumerable<T> items, Func<T, bool> check)
{
T item = items.FirstOrDefault();
if (item != null)
return check(item);
return false;
}
}
}

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

@ -34,12 +34,12 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -34,12 +34,12 @@ namespace ICSharpCode.NRefactory.Parser.VB
ef = new ExpressionFinder();
}
public Lexer(TextReader reader, AbstractLexerState state) : base(reader, state)
public Lexer(TextReader reader, LexerMemento state) : base(reader, state)
{
if (!(state is VBLexerState))
if (!(state is VBLexerMemento))
throw new InvalidOperationException("state must be a VBLexerState");
var vbState = state as VBLexerState;
var vbState = state as VBLexerMemento;
ef = new ExpressionFinder(vbState.ExpressionFinder);
lineEnd = vbState.LineEnd;
isAtLineBegin = vbState.IsAtLineBegin;
@ -421,17 +421,17 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -421,17 +421,17 @@ namespace ICSharpCode.NRefactory.Parser.VB
// 4th rule
// after a less-than (<) in an attribute context
if (prevTokenKind == Tokens.LessThan && ef.CurrentBlock.context == Context.Attribute)
if (prevTokenKind == Tokens.LessThan && ef.InContext(Context.Attribute))
return true;
// 5th rule
// before a greater-than (>) in an attribute context
if (nextTokenKind == Tokens.GreaterThan && ef.CurrentBlock.context == Context.Attribute)
if (nextTokenKind == Tokens.GreaterThan && ef.InContext(Context.Attribute))
return true;
// 6th rule
// after a greater-than (>) in a non-file-level attribute context
if (prevTokenKind == Tokens.GreaterThan && ef.CurrentBlock.context == Context.Attribute)
if (prevTokenKind == Tokens.GreaterThan && ef.InContext(Context.Attribute))
return true;
// 7th rule
@ -440,7 +440,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -440,7 +440,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
Tokens.Where, Tokens.Order, Tokens.By, Tokens.Ascending, Tokens.Descending, Tokens.Take,
Tokens.Skip, Tokens.Let, Tokens.Group, Tokens.Into, Tokens.On, Tokens.While, Tokens.Join };
if ((queryOperators.Contains(prevTokenKind) || queryOperators.Contains(nextTokenKind))
&& ef.CurrentBlock.context == Context.Query)
&& ef.InContext(Context.Query))
return true;
// 8th rule
@ -1133,9 +1133,9 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -1133,9 +1133,9 @@ namespace ICSharpCode.NRefactory.Parser.VB
ef.SetContext(type);
}
public override AbstractLexerState Export()
public override LexerMemento Export()
{
return new VBLexerState() {
return new VBLexerMemento() {
Column = Col,
Line = Line,
EncounteredLineContinuation = encounteredLineContinuation,

2
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBLexerState.cs → src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBLexerMemento.cs

@ -10,7 +10,7 @@ using System.Collections.Generic; @@ -10,7 +10,7 @@ using System.Collections.Generic;
namespace ICSharpCode.NRefactory.Parser.VB
{
public sealed class VBLexerState : AbstractLexerState
public sealed class VBLexerMemento : LexerMemento
{
public bool LineEnd { get; set; }
public bool IsAtLineBegin { get; set; }

2
src/Libraries/NRefactory/Project/Src/ParserFactory.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory @@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory
throw new System.NotSupportedException(language + " not supported.");
}
public static Parser.ILexer CreateLexer(SupportedLanguage language, TextReader textReader, AbstractLexerState state)
public static Parser.ILexer CreateLexer(SupportedLanguage language, TextReader textReader, LexerMemento state)
{
switch (language) {
case SupportedLanguage.CSharp:

46
src/Libraries/NRefactory/Test/Lexer/VBNet/ImplicitLineContinuationTests.cs

@ -93,6 +93,52 @@ End Module"; @@ -93,6 +93,52 @@ End Module";
Tokens.End, Tokens.Module);
}
[Test]
public void Query()
{
string code = @"Module Test
Sub A
Dim q = From x In a
Select x
End Sub
End Module";
ILexer lexer = GenerateLexer(new StringReader(code));
CheckTokens(lexer, Tokens.Module, Tokens.Identifier, Tokens.EOL,
Tokens.Sub, Tokens.Identifier, Tokens.EOL,
Tokens.Dim, Tokens.Identifier, Tokens.Assign, Tokens.From, Tokens.Identifier, Tokens.In, Tokens.Identifier,
Tokens.Select, Tokens.Identifier, Tokens.EOL,
Tokens.End, Tokens.Sub, Tokens.EOL,
Tokens.End, Tokens.Module);
}
[Test]
public void Query1()
{
string code = @"Module Test
Sub A
Dim actions = From a in b Select Sub()
Dim i = 1
Select Case i
End Select
End Sub
End Sub
End Module";
ILexer lexer = GenerateLexer(new StringReader(code));
CheckTokens(lexer, Tokens.Module, Tokens.Identifier, Tokens.EOL,
Tokens.Sub, Tokens.Identifier, Tokens.EOL,
Tokens.Dim, Tokens.Identifier, Tokens.Assign, Tokens.From, Tokens.Identifier, Tokens.In, Tokens.Identifier, Tokens.Select, Tokens.Sub, Tokens.OpenParenthesis, Tokens.CloseParenthesis, Tokens.EOL,
Tokens.Dim, Tokens.Identifier, Tokens.Assign, Tokens.LiteralInteger, Tokens.EOL,
Tokens.Select, Tokens.Case, Tokens.Identifier, Tokens.EOL,
Tokens.End, Tokens.Select, Tokens.EOL,
Tokens.End, Tokens.Sub, Tokens.EOL,
Tokens.End, Tokens.Sub, Tokens.EOL,
Tokens.End, Tokens.Module);
}
#region Helpers
ILexer GenerateLexer(StringReader sr)
{

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

@ -1122,15 +1122,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1122,15 +1122,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}
static void AddVBNetKeywords(List<ICompletionEntry> ar, BitArray keywords)
{
for (int i = 0; i < keywords.Length; i++) {
if (keywords[i]) {
ar.Add(new KeywordEntry(NR.Parser.VB.Tokens.GetTokenString(i)));
}
}
}
/// <summary>
/// Returns code completion entries for given context.
/// </summary>

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -81,14 +82,14 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -81,14 +82,14 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
if (lastExpressionStartOffset < 0)
return new ExpressionResult(null, context);
return MakeResult(text, lastExpressionStartOffset, offset, context);
return MakeResult(text, lastExpressionStartOffset, offset, context, p.GetExpectedSet());
}
ExpressionResult MakeResult(string text, int startOffset, int endOffset, ExpressionContext context)
ExpressionResult MakeResult(string text, int startOffset, int endOffset, ExpressionContext context, BitArray expectedKeywords)
{
return new ExpressionResult(text.Substring(startOffset, endOffset - startOffset).Trim(),
DomRegion.FromLocation(OffsetToLocation(startOffset), OffsetToLocation(endOffset)),
context, null);
context, expectedKeywords);
}
void Init(string text, int offset)
@ -160,10 +161,10 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -160,10 +161,10 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
if (lastExpressionStartOffset >= 0) {
if (offset < tokenOffset) {
// offset is in front of this token
return MakeResult(text, lastExpressionStartOffset, tokenOffset, GetContext(block));
return MakeResult(text, lastExpressionStartOffset, tokenOffset, GetContext(block), p.GetExpectedSet());
} else {
// offset is IN this token
return MakeResult(text, lastExpressionStartOffset, offset, GetContext(block));
return MakeResult(text, lastExpressionStartOffset, offset, GetContext(block), p.GetExpectedSet());
}
} else {
return new ExpressionResult(null, GetContext(block));

Loading…
Cancel
Save