Browse Source

Handled pre processor directives as separate AST node.

newNRvisualizers
Mike Krüger 14 years ago
parent
commit
ec82082a36
  1. 1
      ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
  2. 5
      ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs
  3. 114
      ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs
  4. 2
      ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs
  5. 10
      ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs
  6. 1
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  7. 18
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  8. 9
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs
  9. 53
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  10. 11
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  11. 7
      ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs
  12. 7
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  13. 14
      ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

1
ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs

@ -663,6 +663,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -663,6 +663,7 @@ namespace ICSharpCode.NRefactory.CSharp
public static readonly Role<CSharpTokenNode> Assign = new Role<CSharpTokenNode> ("Assign", CSharpTokenNode.Null);
public static readonly Role<CSharpTokenNode> Colon = new Role<CSharpTokenNode> ("Colon", CSharpTokenNode.Null);
public static readonly Role<Comment> Comment = new Role<Comment> ("Comment");
public static readonly Role<PreProcessorDirective> PreProcessorDirective = new Role<PreProcessorDirective> ("PreProcessorDirective");
public static readonly Role<ErrorNode> Error = new Role<ErrorNode> ("Error");
}

5
ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs

@ -55,6 +55,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -55,6 +55,11 @@ namespace ICSharpCode.NRefactory.CSharp
return VisitChildren (comment, data);
}
public virtual S VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, T data)
{
return VisitChildren (preProcessorDirective, data);
}
public virtual S VisitIdentifier (Identifier identifier, T data)
{
return VisitChildren (identifier, data);

114
ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs

@ -0,0 +1,114 @@ @@ -0,0 +1,114 @@
//
// PreProcessorDirective.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2011 Xamarin Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
namespace ICSharpCode.NRefactory.CSharp
{
public enum PreProcessorDirectiveType : byte
{
Invalid = 0,
Region = 1,
Endregion = 2,
If = 3,
Endif = 4,
Elif = 5,
Else = 6,
Define = 7,
Undef = 8,
Error = 9,
Warning = 10,
Pragma = 11,
Line = 12
}
public class PreProcessorDirective : AstNode, IRelocatable
{
public override NodeType NodeType {
get {
return NodeType.Whitespace;
}
}
public PreProcessorDirectiveType Type {
get;
set;
}
public string Argument {
get;
set;
}
public bool Take {
get;
set;
}
TextLocation startLocation;
public override TextLocation StartLocation {
get {
return startLocation;
}
}
TextLocation endLocation;
public override TextLocation EndLocation {
get {
return endLocation;
}
}
public PreProcessorDirective (PreProcessorDirectiveType type, TextLocation startLocation, TextLocation endLocation)
{
this.Type = type;
this.startLocation = startLocation;
this.endLocation = endLocation;
}
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
int lineDelta = startLocation.Line - this.startLocation.Line;
endLocation = new TextLocation (endLocation.Line + lineDelta, lineDelta != 0 ? endLocation.Column : endLocation.Column + startLocation.Column - this.startLocation.Column);
this.startLocation = startLocation;
}
#endregion
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data = default(T))
{
return visitor.VisitPreProcessorDirective (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
PreProcessorDirective o = other as PreProcessorDirective;
return o != null && Type == o.Type;
}
}
}

2
ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs

@ -137,6 +137,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -137,6 +137,8 @@ namespace ICSharpCode.NRefactory.CSharp
S VisitPrimitiveType(PrimitiveType primitiveType, T data);
S VisitComment(Comment comment, T data);
S VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective, T data);
S VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, T data);
S VisitConstraint(Constraint constraint, T data);
S VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode, T data);

10
ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs

@ -61,6 +61,16 @@ namespace ICSharpCode.NRefactory.CSharp @@ -61,6 +61,16 @@ namespace ICSharpCode.NRefactory.CSharp
return VisitChildren (comment, data);
}
public event Action<PreProcessorDirective, T> PreProcessorDirectiveVisited;
S IAstVisitor<T, S>.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, T data)
{
var handler = PreProcessorDirectiveVisited;
if (handler != null)
handler (preProcessorDirective, data);
return VisitChildren (preProcessorDirective, data);
}
public event Action<Identifier, T> IdentifierVisited;
S IAstVisitor<T, S>.VisitIdentifier (Identifier identifier, T data)

1
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -307,6 +307,7 @@ @@ -307,6 +307,7 @@
<Compile Include="Completion\CSharpParameterCompletionEngine.cs" />
<Compile Include="Completion\ICompletionDataFactory.cs" />
<Compile Include="Completion\IParameterCompletionDataFactory.cs" />
<Compile Include="Ast\GeneralScope\PreProcessorDirective.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">

18
ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -2260,9 +2260,23 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2260,9 +2260,23 @@ namespace ICSharpCode.NRefactory.CSharp
// "1.0 / /*comment*/a", then we need to insert a space in front of the comment.
formatter.Space ();
}
formatter.StartNode(comment);
formatter.StartNode( comment);
formatter.WriteComment (comment.CommentType, comment.Content);
formatter.EndNode(comment);
formatter.EndNode( comment);
lastWritten = LastWritten.Whitespace;
return null;
}
public object VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, object data)
{
if (lastWritten == LastWritten.Division) {
// When there's a comment starting after a division operator
// "1.0 / /*comment*/a", then we need to insert a space in front of the comment.
formatter.Space ();
}
formatter.StartNode (preProcessorDirective);
formatter.WriteIdentifier ("#" + preProcessorDirective.Type.ToString ().ToLower ());
formatter.EndNode (preProcessorDirective);
lastWritten = LastWritten.Whitespace;
return null;
}

9
ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs

@ -1247,9 +1247,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1247,9 +1247,14 @@ namespace ICSharpCode.NRefactory.CSharp
return new CodeTypeReference(primitiveType.Keyword);
}
CodeObject IAstVisitor<object, CodeObject>.VisitComment(Comment comment, object data)
CodeObject IAstVisitor<object, CodeObject>.VisitComment (Comment comment, object data)
{
return new CodeComment(comment.Content, comment.CommentType == CommentType.Documentation);
return new CodeComment (comment.Content, comment.CommentType == CommentType.Documentation);
}
CodeObject IAstVisitor<object, CodeObject>.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, object data)
{
return new CodeComment ("#" + preProcessorDirective.Type.ToString ().ToLower ());
}
CodeObject IAstVisitor<object, CodeObject>.VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, object data)

53
ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs

@ -3261,11 +3261,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3261,11 +3261,9 @@ namespace ICSharpCode.NRefactory.CSharp
static void InsertComments (CompilerCompilationUnit top, ConversionVisitor conversionVisitor)
{
var leaf = GetOuterLeft (conversionVisitor.Unit);
for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) {
var special = top.SpecialsBag.Specials [i];
Comment newLeaf = null;
AstNode newLeaf = null;
var comment = special as SpecialsBag.Comment;
if (comment != null) {
if (conversionVisitor.convertTypeSystemMode && (comment.CommentType != SpecialsBag.CommentType.Documentation))
@ -3278,37 +3276,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3278,37 +3276,14 @@ namespace ICSharpCode.NRefactory.CSharp
Content = comment.Content
};
} else {
// TODO: Proper handling of pre processor directives (atm got treated as comments Ast wise)
var directive = special as SpecialsBag.PreProcessorDirective;
if (directive != null) {
newLeaf = new Comment (CommentType.SingleLine, new TextLocation (directive.Line, directive.Col), new TextLocation (directive.EndLine, directive.EndCol + 1));
if (!directive.Take) {
SpecialsBag.PreProcessorDirective endif = null;
int endifLevel = 0;
for (int j = i + 1; j < top.SpecialsBag.Specials.Count; j++) {
var s = top.SpecialsBag.Specials [j] as SpecialsBag.PreProcessorDirective;
if (s == null)
continue;
if (s.Cmd == Tokenizer.PreprocessorDirective.If) {
endifLevel++;
continue;
}
if (s.Cmd == Tokenizer.PreprocessorDirective.Endif || endifLevel == 0 && s.Cmd == Tokenizer.PreprocessorDirective.Else) {
if (endifLevel == 0) {
endif = s;
i = j;
break;
}
endifLevel--;
}
}
if (endif != null)
newLeaf = new Comment (CommentType.SingleLine, new TextLocation (directive.Line, directive.Col), new TextLocation (endif.EndLine, endif.EndCol));
}
newLeaf = new PreProcessorDirective ((ICSharpCode.NRefactory.CSharp.PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation (directive.Line, directive.Col), new TextLocation (directive.EndLine, directive.EndCol)) {
Argument = directive.Arg,
Take = directive.Take
};
}
}
if (newLeaf == null)
continue;
@ -3321,7 +3296,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3321,7 +3296,11 @@ namespace ICSharpCode.NRefactory.CSharp
leaf = node;
node = node.Parent;
}
node.InsertChildBefore (leaf, newLeaf, AstNode.Roles.Comment);
if (newLeaf is Comment) {
node.InsertChildBefore (leaf, (Comment)newLeaf, AstNode.Roles.Comment);
} else {
node.InsertChildBefore (leaf, (PreProcessorDirective)newLeaf, AstNode.Roles.PreProcessorDirective);
}
leaf = newLeaf;
break;
}
@ -3329,7 +3308,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3329,7 +3308,11 @@ namespace ICSharpCode.NRefactory.CSharp
// insert comment at the end
if (nextLeaf == null) {
var node = leaf.Parent ?? conversionVisitor.Unit;
node.AddChild (newLeaf, AstNode.Roles.Comment);
if (newLeaf is Comment) {
node.AddChild ((Comment)newLeaf, AstNode.Roles.Comment);
} else {
node.AddChild ((PreProcessorDirective)newLeaf, AstNode.Roles.PreProcessorDirective);
}
leaf = newLeaf;
break;
}
@ -3337,7 +3320,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3337,7 +3320,11 @@ namespace ICSharpCode.NRefactory.CSharp
// comment is between 2 nodes
if (leaf.EndLocation <= newLeaf.StartLocation && newLeaf.StartLocation <= nextLeaf.StartLocation) {
var node = leaf.Parent ?? conversionVisitor.Unit;
node.InsertChildAfter (leaf, newLeaf, AstNode.Roles.Comment);
if (newLeaf is Comment) {
node.InsertChildAfter (leaf, (Comment)newLeaf, AstNode.Roles.Comment);
} else {
node.InsertChildAfter (leaf, (PreProcessorDirective)newLeaf, AstNode.Roles.PreProcessorDirective);
}
leaf = newLeaf;
break;
}

11
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs

@ -3350,7 +3350,7 @@ namespace Mono.CSharp @@ -3350,7 +3350,7 @@ namespace Mono.CSharp
if (ParsePreprocessingDirective (true))
continue;
sbag.StartComment (SpecialsBag.CommentType.Multi, false, line, col);
bool directive_expected = false;
while ((c = get_char ()) != -1) {
if (col == 1) {
@ -3364,23 +3364,26 @@ namespace Mono.CSharp @@ -3364,23 +3364,26 @@ namespace Mono.CSharp
continue;
}
if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' )
if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v' ) {
sbag.PushCommentChar (c);
continue;
}
if (c == '#') {
if (ParsePreprocessingDirective (false))
break;
}
sbag.PushCommentChar (c);
directive_expected = false;
}
sbag.EndComment (line, col);
if (c != -1) {
tokens_seen = false;
continue;
}
return Token.EOF;
case '"':
return consume_string (false);

7
ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs

@ -545,6 +545,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" @@ -545,6 +545,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
[Conditional ("FULL_AST")]
public void StartComment (CommentType type, bool startsLine, int startLine, int startCol)
{
inComment = true;
curComment = type;
this.startsLine = startsLine;
this.startLine = startLine;
@ -565,15 +566,21 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format (" @@ -565,15 +566,21 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
contentBuilder.Append (str);
}
bool inComment;
[Conditional ("FULL_AST")]
public void EndComment (int endLine, int endColumn)
{
if (!inComment)
return;
inComment = false;
Specials.Add (new Comment (curComment, startsLine, startLine, startCol, endLine, endColumn, contentBuilder.ToString ()));
}
[Conditional ("FULL_AST")]
public void AddPreProcessorDirective (int startLine, int startCol, int endLine, int endColumn, Tokenizer.PreprocessorDirective cmd, string arg)
{
if (inComment)
EndComment (startLine, startCol);
Specials.Add (new PreProcessorDirective (startLine, startCol, endLine, endColumn, cmd, arg));
}

7
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -3369,11 +3369,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3369,11 +3369,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitComment(Comment comment, object data)
ResolveResult IAstVisitor<object, ResolveResult>.VisitComment (Comment comment, object data)
{
return null;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, object data)
{
return null;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode, object data)
{
return null;

14
ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

@ -2037,16 +2037,22 @@ namespace ICSharpCode.NRefactory.VB.Visitors @@ -2037,16 +2037,22 @@ namespace ICSharpCode.NRefactory.VB.Visitors
return EndNode(primitiveType, new PrimitiveType(typeName));
}
public AstNode VisitComment(CSharp.Comment comment, object data)
public AstNode VisitComment (CSharp.Comment comment, object data)
{
var c = new Comment(comment.Content, comment.CommentType == CSharp.CommentType.Documentation);
var c = new Comment (comment.Content, comment.CommentType == CSharp.CommentType.Documentation);
if (comment.CommentType == CSharp.CommentType.MultiLine)
throw new NotImplementedException();
throw new NotImplementedException ();
return EndNode(comment, c);
return EndNode (comment, c);
}
public AstNode VisitPreProcessorDirective (CSharp.PreProcessorDirective preProcessorDirective, object data)
{
// TODO
return null;
}
public AstNode VisitTypeParameterDeclaration(CSharp.TypeParameterDeclaration typeParameterDeclaration, object data)
{
var param = new TypeParameterDeclaration() {

Loading…
Cancel
Save