2
// <copyright see="prj:///doc/copyright.txt"/>
3
// <license see="prj:///doc/license.txt"/>
4
// <owner name="Daniel Grunwald"/>
5
// <version>$Revision: 4482 $</version>
9
using System.Collections.Generic;
10
using System.Diagnostics;
13
using ICSharpCode.OldNRefactory.Ast;
14
using ICSharpCode.OldNRefactory.Parser;
16
namespace ICSharpCode.OldNRefactory
18
public enum SnippetType
28
/// The snippet parser supports parsing code snippets that are not valid as a full compilation unit.
30
public class SnippetParser
32
readonly SupportedLanguage language;
34
public SnippetParser(SupportedLanguage language)
36
this.language = language;
40
/// Gets the errors of the last call to Parse(). Returns null if parse was not yet called.
42
public Errors Errors { get; private set; }
45
/// Gets the specials of the last call to Parse(). Returns null if parse was not yet called.
47
public List<ISpecial> Specials { get; private set; }
50
/// Gets the snippet type of the last call to Parse(). Returns None if parse was not yet called.
52
public SnippetType SnippetType { get; private set; }
55
/// Parse the code. The result may be a CompilationUnit, an Expression, a list of statements or a list of class
58
public INode Parse(string code)
60
IParser parser = ParserFactory.CreateParser(language, new StringReader(code));
62
this.Errors = parser.Errors;
63
this.Specials = parser.Lexer.SpecialTracker.RetrieveSpecials();
64
this.SnippetType = SnippetType.CompilationUnit;
65
INode result = parser.CompilationUnit;
67
if (this.Errors.Count > 0) {
68
if (language == SupportedLanguage.CSharp) {
69
// SEMICOLON HACK : without a trailing semicolon, parsing expressions does not work correctly
70
parser = ParserFactory.CreateParser(language, new StringReader(code + ";"));
72
parser = ParserFactory.CreateParser(language, new StringReader(code));
74
Expression expression = parser.ParseExpression();
75
if (expression != null && parser.Errors.Count < this.Errors.Count) {
76
this.Errors = parser.Errors;
77
this.Specials = parser.Lexer.SpecialTracker.RetrieveSpecials();
78
this.SnippetType = SnippetType.Expression;
82
if (this.Errors.Count > 0) {
83
parser = ParserFactory.CreateParser(language, new StringReader(code));
84
BlockStatement block = parser.ParseBlock();
85
if (block != null && parser.Errors.Count < this.Errors.Count) {
86
this.Errors = parser.Errors;
87
this.Specials = parser.Lexer.SpecialTracker.RetrieveSpecials();
88
this.SnippetType = SnippetType.Statements;
92
if (this.Errors.Count > 0) {
93
parser = ParserFactory.CreateParser(language, new StringReader(code));
94
List<INode> members = parser.ParseTypeMembers();
95
if (members != null && members.Count > 0 && parser.Errors.Count < this.Errors.Count) {
96
this.Errors = parser.Errors;
97
this.Specials = parser.Lexer.SpecialTracker.RetrieveSpecials();
98
this.SnippetType = SnippetType.TypeMembers;
99
result = new NodeListNode(members);
100
result.StartLocation = members[0].StartLocation;
101
result.EndLocation = members[members.Count - 1].EndLocation;
104
Debug.Assert(result is CompilationUnit || !result.StartLocation.IsEmpty);
105
Debug.Assert(result is CompilationUnit || !result.EndLocation.IsEmpty);
109
sealed class NodeListNode : INode
113
public NodeListNode(List<INode> nodes)
118
public INode Parent {
120
set { throw new NotSupportedException(); }
123
public List<INode> Children {
124
get { return nodes; }
127
public Location StartLocation { get; set; }
128
public Location EndLocation { get; set; }
130
public object UserData { get; set; }
132
public object AcceptChildren(IAstVisitor visitor, object data)
134
foreach (INode n in nodes) {
135
n.AcceptVisitor(visitor, data);
140
public object AcceptVisitor(IAstVisitor visitor, object data)
142
return AcceptChildren(visitor, data);