From c319e924774b3a44583ef35aa7289fda89dc04c2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 10 Jul 2010 09:16:50 +0000 Subject: [PATCH] implemented state handling in ILexer and AbstractLexer to make it publicly available git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6084 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../NRefactory/Project/NRefactory.csproj | 3 + .../Project/Src/Lexer/AbstractLexer.cs | 21 +++++++ .../Project/Src/Lexer/AbstractLexerState.cs | 17 +++++ .../NRefactory/Project/Src/Lexer/ILexer.cs | 12 ++++ .../Project/Src/Lexer/VBNet/Lexer.cs | 62 +++++-------------- .../Project/Src/Lexer/VBNet/VBLexerState.cs | 23 +++++++ .../Project/Src/Lexer/VBNet/XmlModeInfo.cs | 33 ++++++++++ .../NRefactory/Project/Src/ParserFactory.cs | 13 ++++ 8 files changed, 136 insertions(+), 48 deletions(-) create mode 100644 src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexerState.cs create mode 100644 src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBLexerState.cs create mode 100644 src/Libraries/NRefactory/Project/Src/Lexer/VBNet/XmlModeInfo.cs diff --git a/src/Libraries/NRefactory/Project/NRefactory.csproj b/src/Libraries/NRefactory/Project/NRefactory.csproj index dc1953056e..ea015e9367 100644 --- a/src/Libraries/NRefactory/Project/NRefactory.csproj +++ b/src/Libraries/NRefactory/Project/NRefactory.csproj @@ -61,6 +61,7 @@ + ExpressionFinder.atg @@ -90,6 +91,8 @@ Configuration\GlobalAssemblyInfo.cs + + diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs b/src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs index 4a138eabed..e0cb082431 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs @@ -196,6 +196,13 @@ namespace ICSharpCode.NRefactory.Parser this.reader = new LATextReader(reader); } + protected AbstractLexer(TextReader reader, AbstractLexerState state) + : this(reader) + { + SetInitialLocation(new Location(state.Column, state.Line)); + lastToken = new Token(state.PrevTokenKind, 0, 0); + } + #region System.IDisposable interface implementation public virtual void Dispose() { @@ -360,5 +367,19 @@ namespace ICSharpCode.NRefactory.Parser /// After the call, Lexer.LookAhead will be the block-closing token. /// public abstract void SkipCurrentBlock(int targetToken); + + public event EventHandler SavepointReached; + + protected virtual void OnSavepointReached(EventArgs e) + { + if (SavepointReached != null) { + SavepointReached(this, e); + } + } + + public virtual AbstractLexerState Export() + { + throw new NotSupportedException(); + } } } diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexerState.cs b/src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexerState.cs new file mode 100644 index 0000000000..666954df76 --- /dev/null +++ b/src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexerState.cs @@ -0,0 +1,17 @@ +// +// +// +// +// $Revision$ +// +using System; + +namespace ICSharpCode.NRefactory.Parser +{ + public abstract class AbstractLexerState + { + public int Line { get; set; } + public int Column { get; set; } + public int PrevTokenKind { get; set; } + } +} diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs b/src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs index 748263c62f..a5f9378b13 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs @@ -106,5 +106,17 @@ namespace ICSharpCode.NRefactory.Parser /// After the call, Lexer.LookAhead will be the block-closing token. /// void SkipCurrentBlock(int targetToken); + + /// + /// 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. + /// + AbstractLexerState Export(); + + /// + /// Is fired by the lexer as soon as a savepoint is reached. + /// The Export-method can be used to retrieve the current state. + /// + event EventHandler SavepointReached; } } diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs index 33127a2b80..c5c860059a 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs @@ -34,17 +34,19 @@ namespace ICSharpCode.NRefactory.Parser.VB ef = new ExpressionFinder(); } - public Lexer(TextReader reader, LexerState state) : base(reader) + public Lexer(TextReader reader, AbstractLexerState state) : base(reader, state) { - ef = new ExpressionFinder(state.ExpressionFinder); - SetInitialLocation(new Location(state.Column, state.Line)); - lineEnd = state.LineEnd; - isAtLineBegin = state.IsAtLineBegin; - lastToken = new Token(state.PrevTokenKind, 0, 0); - encounteredLineContinuation = state.EncounteredLineContinuation; - misreadExclamationMarkAsTypeCharacter = state.MisreadExclamationMarkAsTypeCharacter; - xmlModeStack = new Stack(state.XmlModeInfoStack.Select(i => (XmlModeInfo)i.Clone()).Reverse()); - inXmlMode = state.InXmlMode; + if (!(state is VBLexerState)) + throw new InvalidOperationException("state must be a VBLexerState"); + + var vbState = state as VBLexerState; + ef = new ExpressionFinder(vbState.ExpressionFinder); + lineEnd = vbState.LineEnd; + isAtLineBegin = vbState.IsAtLineBegin; + encounteredLineContinuation = vbState.EncounteredLineContinuation; + misreadExclamationMarkAsTypeCharacter = vbState.MisreadExclamationMarkAsTypeCharacter; + xmlModeStack = new Stack(vbState.XmlModeInfoStack.Select(i => (XmlModeInfo)i.Clone()).Reverse()); + inXmlMode = vbState.InXmlMode; } Token NextInternal() @@ -1131,9 +1133,9 @@ namespace ICSharpCode.NRefactory.Parser.VB ef.SetContext(type); } - public LexerState Export() + public override AbstractLexerState Export() { - return new LexerState() { + return new VBLexerState() { Column = Col, Line = Line, EncounteredLineContinuation = encounteredLineContinuation, @@ -1147,40 +1149,4 @@ namespace ICSharpCode.NRefactory.Parser.VB }; } } - - public class XmlModeInfo : ICloneable - { - public bool inXmlTag, inXmlCloseTag, isDocumentStart; - public int level; - - public XmlModeInfo(bool isSpecial) - { - level = isSpecial ? -1 : 0; - inXmlTag = inXmlCloseTag = isDocumentStart = false; - } - - public object Clone() - { - return new XmlModeInfo(false) { - inXmlCloseTag = this.inXmlCloseTag, - inXmlTag = this.inXmlTag, - isDocumentStart = this.isDocumentStart, - level = this.level - }; - } - } - - public class LexerState - { - public bool LineEnd { get; set; } - public bool IsAtLineBegin { get; set; } - public bool MisreadExclamationMarkAsTypeCharacter { get; set; } - public bool EncounteredLineContinuation { get; set; } - public ExpressionFinderState ExpressionFinder { get; set; } - public Stack XmlModeInfoStack { get; set; } - public bool InXmlMode { get; set; } - public int Line { get; set; } - public int Column { get; set; } - public int PrevTokenKind { get; set; } - } } diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBLexerState.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBLexerState.cs new file mode 100644 index 0000000000..b6cd352cb7 --- /dev/null +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBLexerState.cs @@ -0,0 +1,23 @@ +// +// +// +// +// $Revision: 6083 $ +// + +using System; +using System.Collections.Generic; + +namespace ICSharpCode.NRefactory.Parser.VB +{ + public sealed class VBLexerState : AbstractLexerState + { + public bool LineEnd { get; set; } + public bool IsAtLineBegin { get; set; } + public bool MisreadExclamationMarkAsTypeCharacter { get; set; } + public bool EncounteredLineContinuation { get; set; } + public ExpressionFinderState ExpressionFinder { get; set; } + public Stack XmlModeInfoStack { get; set; } + public bool InXmlMode { get; set; } + } +} diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/XmlModeInfo.cs b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/XmlModeInfo.cs new file mode 100644 index 0000000000..e3782f3f98 --- /dev/null +++ b/src/Libraries/NRefactory/Project/Src/Lexer/VBNet/XmlModeInfo.cs @@ -0,0 +1,33 @@ +// +// +// +// +// $Revision: 6083 $ +// + +using System; + +namespace ICSharpCode.NRefactory.Parser.VB +{ + public class XmlModeInfo : ICloneable + { + public bool inXmlTag, inXmlCloseTag, isDocumentStart; + public int level; + + public XmlModeInfo(bool isSpecial) + { + level = isSpecial ? -1 : 0; + inXmlTag = inXmlCloseTag = isDocumentStart = false; + } + + public object Clone() + { + return new XmlModeInfo(false) { + inXmlCloseTag = this.inXmlCloseTag, + inXmlTag = this.inXmlTag, + isDocumentStart = this.isDocumentStart, + level = this.level + }; + } + } +} diff --git a/src/Libraries/NRefactory/Project/Src/ParserFactory.cs b/src/Libraries/NRefactory/Project/Src/ParserFactory.cs index 6f5934ae8e..7673a18fe6 100644 --- a/src/Libraries/NRefactory/Project/Src/ParserFactory.cs +++ b/src/Libraries/NRefactory/Project/Src/ParserFactory.cs @@ -8,6 +8,7 @@ using System; using System.IO; using System.Text; +using ICSharpCode.NRefactory.Parser; namespace ICSharpCode.NRefactory { @@ -32,6 +33,18 @@ namespace ICSharpCode.NRefactory throw new System.NotSupportedException(language + " not supported."); } + public static Parser.ILexer CreateLexer(SupportedLanguage language, TextReader textReader, AbstractLexerState state) + { + switch (language) { + case SupportedLanguage.CSharp: + //return new ICSharpCode.NRefactory.Parser.CSharp.Lexer(textReader, state); + throw new System.NotSupportedException("C# Lexer does not support loading a previous state."); + case SupportedLanguage.VBNet: + return new ICSharpCode.NRefactory.Parser.VB.Lexer(textReader, state); + } + throw new System.NotSupportedException(language + " not supported."); + } + public static IParser CreateParser(SupportedLanguage language, TextReader textReader) { Parser.ILexer lexer = CreateLexer(language, textReader);