Browse Source

* Src/Parser/IParser.cs:

* Src/Lexer/VBNet/Lexer.cs:
* Src/Lexer/CSharp/Lexer.cs:
* Src/Lexer/AbstractLexer.cs:
* Src/Parser/AbstractParser.cs:
* Src/Lexer/Special/Comment.cs:
* Src/Parser/VBNet/VBNetParser.cs:
* Src/Lexer/Special/TagComment.cs:
* Src/Parser/CSharp/CSharpParser.cs:
* Src/Lexer/Special/SpecialTracker.cs:
* Src/Lexer/CSharp/ConditionalCompilation.cs:
* Src/Lexer/Special/PreProcessingDirective.cs:
* Src/PrettyPrinter/AbstractOutputFormatter.cs:
* Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs: Added some
  nrefactory features for monodevelop.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3845 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Mike Krüger 17 years ago
parent
commit
f71ba19cae
  1. 18
      src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs
  2. 2
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/ConditionalCompilation.cs
  3. 39
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Lexer.cs
  4. 12
      src/Libraries/NRefactory/Project/Src/Lexer/Special/Comment.cs
  5. 10
      src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs
  6. 6
      src/Libraries/NRefactory/Project/Src/Lexer/Special/SpecialTracker.cs
  7. 2
      src/Libraries/NRefactory/Project/Src/Lexer/Special/TagComment.cs
  8. 9
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  9. 1
      src/Libraries/NRefactory/Project/Src/Parser/AbstractParser.cs
  10. 8
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs
  11. 1
      src/Libraries/NRefactory/Project/Src/Parser/IParser.cs
  12. 6
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs
  13. 5
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/AbstractOutputFormatter.cs
  14. 8
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

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

@ -63,6 +63,7 @@ namespace ICSharpCode.NRefactory.Parser
if ((val == '\r' && reader.Peek() != '\n') || val == '\n') { if ((val == '\r' && reader.Peek() != '\n') || val == '\n') {
++line; ++line;
col = 1; col = 1;
LineBreak ();
} }
return val; return val;
} }
@ -230,19 +231,30 @@ namespace ICSharpCode.NRefactory.Parser
errors.Error(line, col, String.Format("Invalid hex number '" + digit + "'")); errors.Error(line, col, String.Format("Invalid hex number '" + digit + "'"));
return 0; return 0;
} }
protected Location lastLineEnd = new Location (1, 1);
protected Location curLineEnd = new Location (1, 1);
protected void LineBreak ()
{
lastLineEnd = curLineEnd;
curLineEnd = new Location (col - 1, line);
}
protected bool HandleLineEnd(char ch) protected bool HandleLineEnd(char ch)
{ {
// Handle MS-DOS or MacOS line ends. // Handle MS-DOS or MacOS line ends.
if (ch == '\r') { if (ch == '\r') {
if (reader.Peek() == '\n') { // MS-DOS line end '\r\n' if (reader.Peek() == '\n') { // MS-DOS line end '\r\n'
ReaderRead(); ReaderRead(); // LineBreak (); called by ReaderRead ();
return true; return true;
} else { // assume MacOS line end which is '\r' } else { // assume MacOS line end which is '\r'
LineBreak ();
return true; return true;
} }
} }
return ch == '\n'; if (ch == '\n') {
LineBreak ();
return true;
}
return false;
} }
protected void SkipToEndOfLine() protected void SkipToEndOfLine()

2
src/Libraries/NRefactory/Project/Src/Lexer/CSharp/ConditionalCompilation.cs

@ -12,7 +12,7 @@ using ICSharpCode.NRefactory.Visitors;
namespace ICSharpCode.NRefactory.Parser.CSharp namespace ICSharpCode.NRefactory.Parser.CSharp
{ {
sealed class ConditionalCompilation : AbstractAstVisitor public sealed class ConditionalCompilation : AbstractAstVisitor
{ {
static readonly object SymbolDefined = new object(); static readonly object SymbolDefined = new object();
Dictionary<string, object> symbols = new Dictionary<string, object>(); Dictionary<string, object> symbols = new Dictionary<string, object>();

39
src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Lexer.cs

@ -15,6 +15,8 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
{ {
internal sealed class Lexer : AbstractLexer internal sealed class Lexer : AbstractLexer
{ {
bool isAtLineBegin = true;
public Lexer(TextReader reader) : base(reader) public Lexer(TextReader reader) : base(reader)
{ {
} }
@ -24,7 +26,10 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
int nextChar; int nextChar;
char ch; char ch;
bool hadLineEnd = false; bool hadLineEnd = false;
if (Line == 1 && Col == 1) hadLineEnd = true; // beginning of document if (Line == 1 && Col == 1) {
isAtLineBegin = true;
hadLineEnd = true; // beginning of document
}
while ((nextChar = ReaderRead()) != -1) { while ((nextChar = ReaderRead()) != -1) {
Token token; Token token;
@ -42,6 +47,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
} }
HandleLineEnd((char)nextChar); HandleLineEnd((char)nextChar);
hadLineEnd = true; hadLineEnd = true;
isAtLineBegin = true;
continue; continue;
case '/': case '/':
int peek = ReaderPeek(); int peek = ReaderPeek();
@ -49,19 +55,24 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
ReadComment(); ReadComment();
continue; continue;
} else { } else {
isAtLineBegin = false;
token = ReadOperator('/'); token = ReadOperator('/');
} }
break; break;
case '#': case '#':
ReadPreProcessingDirective(); ReadPreProcessingDirective();
isAtLineBegin = false;
continue; continue;
case '"': case '"':
token = ReadString(); token = ReadString();
isAtLineBegin = false;
break; break;
case '\'': case '\'':
token = ReadChar(); token = ReadChar();
isAtLineBegin = false;
break; break;
case '@': case '@':
isAtLineBegin = false;
int next = ReaderRead(); int next = ReaderRead();
if (next == -1) { if (next == -1) {
errors.Error(Line, Col, String.Format("EOF after @")); errors.Error(Line, Col, String.Format("EOF after @"));
@ -83,6 +94,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
} }
break; break;
default: default:
isAtLineBegin = false; // non-ws chars are handled here
ch = (char)nextChar; ch = (char)nextChar;
if (Char.IsLetter(ch) || ch == '_' || ch == '\\') { if (Char.IsLetter(ch) || ch == '_' || ch == '\\') {
int x = Col - 1; // Col was incremented above, but we want the start of the identifier int x = Col - 1; // Col was incremented above, but we want the start of the identifier
@ -780,6 +792,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
switch (ReaderRead()) { switch (ReaderRead()) {
case '*': case '*':
ReadMultiLineComment(); ReadMultiLineComment();
isAtLineBegin = false;
break; break;
case '/': case '/':
if (ReaderPeek() == '/') { if (ReaderPeek() == '/') {
@ -788,6 +801,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
} else { } else {
ReadSingleLineComment(CommentType.SingleLine); ReadSingleLineComment(CommentType.SingleLine);
} }
isAtLineBegin = true;
break; break;
default: default:
errors.Error(Line, Col, String.Format("Error while reading comment")); errors.Error(Line, Col, String.Format("Error while reading comment"));
@ -820,7 +834,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
if (specialCommentHash.ContainsKey(tag)) { if (specialCommentHash.ContainsKey(tag)) {
Location p = new Location(Col, Line); Location p = new Location(Col, Line);
string comment = ch + ReadToEndOfLine(); string comment = ch + ReadToEndOfLine();
this.TagComments.Add(new TagComment(tag, comment, p, new Location(Col, Line))); this.TagComments.Add(new TagComment(tag, comment, isAtLineBegin, p, new Location(Col, Line)));
sb.Append(comment); sb.Append(comment);
break; break;
} }
@ -834,7 +848,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
if (this.SkipAllComments) { if (this.SkipAllComments) {
SkipToEndOfLine(); SkipToEndOfLine();
} else { } else {
specialTracker.StartComment(commentType, new Location(Col, Line)); specialTracker.StartComment(commentType, isAtLineBegin, new Location(Col, Line));
specialTracker.AddString(ReadCommentToEOL()); specialTracker.AddString(ReadCommentToEOL());
specialTracker.FinishComment(new Location(Col, Line)); specialTracker.FinishComment(new Location(Col, Line));
} }
@ -854,7 +868,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
} }
} }
} else { } else {
specialTracker.StartComment(CommentType.Block, new Location(Col, Line)); specialTracker.StartComment(CommentType.Block, isAtLineBegin, new Location(Col, Line));
// sc* = special comment handling (TO DO markers) // sc* = special comment handling (TO DO markers)
string scTag = null; // is set to non-null value when we are inside a comment marker string scTag = null; // is set to non-null value when we are inside a comment marker
@ -866,7 +880,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
if (HandleLineEnd(ch)) { if (HandleLineEnd(ch)) {
if (scTag != null) { if (scTag != null) {
this.TagComments.Add(new TagComment(scTag, scCurWord.ToString(), scStartLocation, new Location(Col, Line))); this.TagComments.Add(new TagComment(scTag, scCurWord.ToString(), isAtLineBegin, scStartLocation, new Location(Col, Line)));
scTag = null; scTag = null;
} }
scCurWord.Length = 0; scCurWord.Length = 0;
@ -877,7 +891,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
// End of multiline comment reached ? // End of multiline comment reached ?
if (ch == '*' && ReaderPeek() == '/') { if (ch == '*' && ReaderPeek() == '/') {
if (scTag != null) { if (scTag != null) {
this.TagComments.Add(new TagComment(scTag, scCurWord.ToString(), scStartLocation, new Location(Col, Line))); this.TagComments.Add(new TagComment(scTag, scCurWord.ToString(), isAtLineBegin, scStartLocation, new Location(Col, Line)));
} }
ReaderRead(); ReaderRead();
specialTracker.FinishComment(new Location(Col, Line)); specialTracker.FinishComment(new Location(Col, Line));
@ -919,13 +933,16 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
lastToken = curToken; lastToken = curToken;
curToken = curToken.next; curToken = curToken.next;
} }
isAtLineBegin = true;
int nextChar; int nextChar;
while ((nextChar = ReaderRead()) != -1) { while ((nextChar = ReaderRead()) != -1) {
switch (nextChar) { switch (nextChar) {
case '{': case '{':
isAtLineBegin = false;
braceCount++; braceCount++;
break; break;
case '}': case '}':
isAtLineBegin = false;
if (--braceCount < 0) { if (--braceCount < 0) {
curToken = new Token(Tokens.CloseCurlyBrace, Col - 1, Line); curToken = new Token(Tokens.CloseCurlyBrace, Col - 1, Line);
return; return;
@ -936,19 +953,24 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
if (peek == '/' || peek == '*') { if (peek == '/' || peek == '*') {
ReadComment(); ReadComment();
} }
isAtLineBegin = false;
break; break;
case '#': case '#':
ReadPreProcessingDirective(); ReadPreProcessingDirective();
isAtLineBegin = false;
break; break;
case '"': case '"':
ReadString(); ReadString();
isAtLineBegin = false;
break; break;
case '\'': case '\'':
ReadChar(); ReadChar();
isAtLineBegin = false;
break; break;
case '\r': case '\r':
case '\n': case '\n':
HandleLineEnd((char)nextChar); HandleLineEnd((char)nextChar);
isAtLineBegin = true;
break; break;
case '@': case '@':
int next = ReaderRead(); int next = ReaderRead();
@ -957,6 +979,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
} else if (next == '"') { } else if (next == '"') {
ReadVerbatimString(); ReadVerbatimString();
} }
isAtLineBegin = false;
break; break;
} }
} }
@ -1072,7 +1095,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
} }
SkipToEndOfLine(); // skip comment SkipToEndOfLine(); // skip comment
} }
return new PreprocessingDirective(directive, null, start, endLocation) { Expression = expr }; return new PreprocessingDirective(directive, null, start, endLocation) { Expression = expr, LastLineEnd = lastLineEnd };
} else { } else {
Location endLocation = new Location(Col, Line); Location endLocation = new Location(Col, Line);
string arg = ReadToEndOfLine(); string arg = ReadToEndOfLine();
@ -1081,7 +1104,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
if (pos >= 0) if (pos >= 0)
arg = arg.Substring(0, pos); arg = arg.Substring(0, pos);
arg = arg.Trim(); arg = arg.Trim();
return new PreprocessingDirective(directive, arg, start, endLocation); return new PreprocessingDirective(directive, arg, start, endLocation) { LastLineEnd = lastLineEnd };
} }
} }

12
src/Libraries/NRefactory/Project/Src/Lexer/Special/Comment.cs

@ -32,11 +32,21 @@ namespace ICSharpCode.NRefactory
} }
} }
public Comment(CommentType commentType, string comment, Location startPosition, Location endPosition) /// <value>
/// Is true, when the comment is at line start or only whitespaces
/// between line and comment start.
/// </value>
public bool CommentStartsLine {
get;
set;
}
public Comment(CommentType commentType, string comment, bool commentStartsLine, Location startPosition, Location endPosition)
: base(startPosition, endPosition) : base(startPosition, endPosition)
{ {
this.commentType = commentType; this.commentType = commentType;
this.comment = comment; this.comment = comment;
this.CommentStartsLine = commentStartsLine;
} }
public override string ToString() public override string ToString()

10
src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs

@ -128,6 +128,16 @@ namespace ICSharpCode.NRefactory
set { expression = value ?? Ast.Expression.Null; } set { expression = value ?? Ast.Expression.Null; }
} }
/// <value>
/// The end position of the pre processor directive line.
/// May be != EndPosition.
/// </value>
public Location LastLineEnd {
get;
set;
}
public override string ToString() public override string ToString()
{ {
return String.Format("[PreProcessingDirective: Cmd = {0}, Arg = {1}]", return String.Format("[PreProcessingDirective: Cmd = {0}, Arg = {1}]",

6
src/Libraries/NRefactory/Project/Src/Lexer/Special/SpecialTracker.cs

@ -18,6 +18,7 @@ namespace ICSharpCode.NRefactory.Parser
CommentType currentCommentType; CommentType currentCommentType;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Location startPosition; Location startPosition;
bool commentStartsLine;
public List<ISpecial> CurrentSpecials { public List<ISpecial> CurrentSpecials {
get { get {
@ -53,11 +54,12 @@ namespace ICSharpCode.NRefactory.Parser
} }
// used for comment tracking // used for comment tracking
public void StartComment(CommentType commentType, Location startPosition) public void StartComment(CommentType commentType, bool commentStartsLine, Location startPosition)
{ {
this.currentCommentType = commentType; this.currentCommentType = commentType;
this.startPosition = startPosition; this.startPosition = startPosition;
this.sb.Length = 0; this.sb.Length = 0;
this.commentStartsLine = commentStartsLine;
} }
public void AddChar(char c) public void AddChar(char c)
@ -72,7 +74,7 @@ namespace ICSharpCode.NRefactory.Parser
public void FinishComment(Location endPosition) public void FinishComment(Location endPosition)
{ {
currentSpecials.Add(new Comment(currentCommentType, sb.ToString(), startPosition, endPosition)); currentSpecials.Add(new Comment(currentCommentType, sb.ToString(), commentStartsLine, startPosition, endPosition));
} }
} }
} }

2
src/Libraries/NRefactory/Project/Src/Lexer/Special/TagComment.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.NRefactory.Parser
} }
} }
public TagComment(string tag, string comment, Location startPosition, Location endPosition) : base(CommentType.SingleLine, comment, startPosition, endPosition) public TagComment(string tag, string comment, bool commentStartsLine, Location startPosition, Location endPosition) : base(CommentType.SingleLine, comment, commentStartsLine, startPosition, endPosition)
{ {
this.tag = tag; this.tag = tag;
} }

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

@ -15,6 +15,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
internal sealed class Lexer : AbstractLexer internal sealed class Lexer : AbstractLexer
{ {
bool lineEnd = true; bool lineEnd = true;
bool isAtLineBegin = false; // TODO: handle line begin, if neccessarry
public Lexer(TextReader reader) : base(reader) public Lexer(TextReader reader) : base(reader)
{ {
@ -576,11 +577,11 @@ namespace ICSharpCode.NRefactory.Parser.VB
if (missingApostrophes > 0) { if (missingApostrophes > 0) {
if (ch == '\'' || ch == '\u2018' || ch == '\u2019') { if (ch == '\'' || ch == '\u2018' || ch == '\u2019') {
if (--missingApostrophes == 0) { if (--missingApostrophes == 0) {
specialTracker.StartComment(CommentType.Documentation, startPos); specialTracker.StartComment(CommentType.Documentation, isAtLineBegin, startPos);
sb.Length = 0; sb.Length = 0;
} }
} else { } else {
specialTracker.StartComment(CommentType.SingleLine, startPos); specialTracker.StartComment(CommentType.SingleLine, isAtLineBegin, startPos);
missingApostrophes = 0; missingApostrophes = 0;
} }
} }
@ -594,7 +595,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
if (specialCommentHash.ContainsKey(tag)) { if (specialCommentHash.ContainsKey(tag)) {
Location p = new Location(Col, Line); Location p = new Location(Col, Line);
string comment = ch + ReadToEndOfLine(); string comment = ch + ReadToEndOfLine();
this.TagComments.Add(new TagComment(tag, comment, p, new Location(Col, Line))); this.TagComments.Add(new TagComment(tag, comment, isAtLineBegin, p, new Location(Col, Line)));
sb.Append(comment); sb.Append(comment);
break; break;
} }
@ -602,7 +603,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
} }
} }
if (missingApostrophes > 0) { if (missingApostrophes > 0) {
specialTracker.StartComment(CommentType.SingleLine, startPos); specialTracker.StartComment(CommentType.SingleLine, isAtLineBegin, startPos);
} }
specialTracker.AddString(sb.ToString()); specialTracker.AddString(sb.ToString());
specialTracker.FinishComment(new Location(Col, Line)); specialTracker.FinishComment(new Location(Col, Line));

1
src/Libraries/NRefactory/Project/Src/Parser/AbstractParser.cs

@ -63,6 +63,7 @@ namespace ICSharpCode.NRefactory.Parser
public abstract void Parse(); public abstract void Parse();
public abstract TypeReference ParseTypeReference ();
public abstract Expression ParseExpression(); public abstract Expression ParseExpression();
public abstract BlockStatement ParseBlock(); public abstract BlockStatement ParseBlock();
public abstract List<INode> ParseTypeMembers(); public abstract List<INode> ParseTypeMembers();

8
src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs

@ -56,6 +56,14 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
compilationUnit.AcceptVisitor(new SetParentVisitor(), null); compilationUnit.AcceptVisitor(new SetParentVisitor(), null);
} }
public override TypeReference ParseTypeReference ()
{
lexer.NextToken();
TypeReference type;
Type(out type);
return type;
}
public override Expression ParseExpression() public override Expression ParseExpression()
{ {
lexer.NextToken(); lexer.NextToken();

1
src/Libraries/NRefactory/Project/Src/Parser/IParser.cs

@ -35,6 +35,7 @@ namespace ICSharpCode.NRefactory
void Parse(); void Parse();
Expression ParseExpression(); Expression ParseExpression();
TypeReference ParseTypeReference ();
BlockStatement ParseBlock(); BlockStatement ParseBlock();
List<INode> ParseTypeMembers(); List<INode> ParseTypeMembers();
} }

6
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs

@ -65,6 +65,12 @@ namespace ICSharpCode.NRefactory.Parser.VB
compilationUnit.AcceptVisitor(new SetParentVisitor(), null); compilationUnit.AcceptVisitor(new SetParentVisitor(), null);
} }
public override TypeReference ParseTypeReference ()
{
// TODO
return null;
}
public override Expression ParseExpression() public override Expression ParseExpression()
{ {
lexer.NextToken(); lexer.NextToken();

5
src/Libraries/NRefactory/Project/Src/PrettyPrinter/AbstractOutputFormatter.cs

@ -89,6 +89,11 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
} }
} }
public void Reset ()
{
text.Length = 0;
}
public void Space() public void Space()
{ {
text.Append(' '); text.Append(' ');

8
src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

@ -2607,6 +2607,14 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return node.AcceptVisitor(this, data); return node.AcceptVisitor(this, data);
} }
/// <summary>
/// Resets the output formatter, sets Text to string.Empty.
/// </summary>
public void Reset ()
{
outputFormatter.Reset ();
}
public void AppendCommaSeparatedList<T>(ICollection<T> list) where T : class, INode public void AppendCommaSeparatedList<T>(ICollection<T> list) where T : class, INode
{ {
if (list != null) { if (list != null) {

Loading…
Cancel
Save