Browse Source

Merge branch 'master' of github.com:icsharpcode/NRefactory

newNRvisualizers
Mike Krüger 14 years ago
parent
commit
af7cccffaa
  1. 11
      ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
  2. 10
      ICSharpCode.NRefactory.CSharp/Ast/CSharpTokenNode.cs
  3. 10
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/EmptyExpression.cs
  4. 9
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/PrimitiveExpression.cs
  5. 12
      ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Comment.cs
  6. 12
      ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs
  7. 35
      ICSharpCode.NRefactory.CSharp/Ast/IRelocatable.cs
  8. 10
      ICSharpCode.NRefactory.CSharp/Ast/Identifier.cs
  9. 11
      ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs
  10. 10
      ICSharpCode.NRefactory.CSharp/Ast/Statements/EmptyStatement.cs
  11. 646
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  12. 120
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
  13. 22
      ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
  14. 22
      ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
  15. 1
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  16. 2
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs
  17. 38
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  18. 4
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  19. 3
      ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs
  20. 6
      ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs
  21. 4
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  22. 26
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs
  23. 1
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs
  24. 2
      ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs

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

@ -273,6 +273,17 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
/// <summary>
/// Gets the ancestors of this node (including this node itself)
/// </summary>
public IEnumerable<AstNode> AncestorsAndSelf {
get {
for (AstNode cur = this; cur != null; cur = cur.parent) {
yield return cur;
}
}
}
/// <summary> /// <summary>
/// Gets all descendants of this node (excluding this node itself). /// Gets all descendants of this node (excluding this node itself).
/// </summary> /// </summary>

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

@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <remarks> /// <remarks>
/// In all non null c# token nodes the Role of a CSharpToken must be a TokenRole. /// In all non null c# token nodes the Role of a CSharpToken must be a TokenRole.
/// </remarks> /// </remarks>
public class CSharpTokenNode : AstNode, IRelocatable public class CSharpTokenNode : AstNode
{ {
public static new readonly CSharpTokenNode Null = new NullCSharpTokenNode (); public static new readonly CSharpTokenNode Null = new NullCSharpTokenNode ();
class NullCSharpTokenNode : CSharpTokenNode class NullCSharpTokenNode : CSharpTokenNode
@ -100,14 +100,6 @@ namespace ICSharpCode.NRefactory.CSharp
this.startLocation = location; this.startLocation = location;
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
ThrowIfFrozen();
this.startLocation = startLocation;
}
#endregion
public override string GetText (CSharpFormattingOptions formattingOptions = null) public override string GetText (CSharpFormattingOptions formattingOptions = null)
{ {
if (!(Role is TokenRole)) if (!(Role is TokenRole))

10
ICSharpCode.NRefactory.CSharp/Ast/Expressions/EmptyExpression.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary> /// <summary>
/// Type&lt;[EMPTY]&gt; /// Type&lt;[EMPTY]&gt;
/// </summary> /// </summary>
public class EmptyExpression : Expression, IRelocatable public class EmptyExpression : Expression
{ {
TextLocation location; TextLocation location;
@ -55,14 +55,6 @@ namespace ICSharpCode.NRefactory.CSharp
this.location = location; this.location = location;
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
ThrowIfFrozen();
this.location = startLocation;
}
#endregion
public override void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitEmptyExpression (this); visitor.VisitEmptyExpression (this);

9
ICSharpCode.NRefactory.CSharp/Ast/Expressions/PrimitiveExpression.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary> /// <summary>
/// Represents a literal value. /// Represents a literal value.
/// </summary> /// </summary>
public class PrimitiveExpression : Expression, IRelocatable public class PrimitiveExpression : Expression
{ {
public static readonly object AnyValue = new object(); public static readonly object AnyValue = new object();
@ -88,13 +88,6 @@ namespace ICSharpCode.NRefactory.CSharp
this.literalValue = literalValue ?? ""; this.literalValue = literalValue ?? "";
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
this.startLocation = startLocation;
}
#endregion
public override void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitPrimitiveExpression (this); visitor.VisitPrimitiveExpression (this);

12
ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Comment.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.NRefactory.CSharp
MultiLineDocumentation MultiLineDocumentation
} }
public class Comment : AstNode, IRelocatable public class Comment : AstNode
{ {
public override NodeType NodeType { public override NodeType NodeType {
get { get {
@ -106,16 +106,6 @@ namespace ICSharpCode.NRefactory.CSharp
this.endLocation = endLocation; this.endLocation = endLocation;
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
ThrowIfFrozen();
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 void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitComment (this); visitor.VisitComment (this);

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

@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp
Line = 12 Line = 12
} }
public class PreProcessorDirective : AstNode, IRelocatable public class PreProcessorDirective : AstNode
{ {
public override NodeType NodeType { public override NodeType NodeType {
get { get {
@ -93,16 +93,6 @@ namespace ICSharpCode.NRefactory.CSharp
this.endLocation = endLocation; this.endLocation = endLocation;
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
ThrowIfFrozen();
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 void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitPreProcessorDirective (this); visitor.VisitPreProcessorDirective (this);

35
ICSharpCode.NRefactory.CSharp/Ast/IRelocatable.cs

@ -1,35 +0,0 @@
//
// IRelocationable.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
//
// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
//
// 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 interface IRelocatable
{
void SetStartLocation (TextLocation startLocation);
}
}

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

@ -28,7 +28,7 @@ using System;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public class Identifier : AstNode, IRelocatable public class Identifier : AstNode
{ {
public new static readonly Identifier Null = new NullIdentifier (); public new static readonly Identifier Null = new NullIdentifier ();
sealed class NullIdentifier : Identifier sealed class NullIdentifier : Identifier
@ -98,14 +98,6 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
ThrowIfFrozen();
this.startLocation = startLocation;
}
#endregion
public override TextLocation EndLocation { public override TextLocation EndLocation {
get { get {
return new TextLocation (StartLocation.Line, StartLocation.Column + (Name ?? "").Length + (IsVerbatim ? 1 : 0)); return new TextLocation (StartLocation.Line, StartLocation.Column + (Name ?? "").Length + (IsVerbatim ? 1 : 0));

11
ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs

@ -32,7 +32,7 @@ using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public class PrimitiveType : AstType, IRelocatable public class PrimitiveType : AstType
{ {
TextLocation location; TextLocation location;
string keyword = string.Empty; string keyword = string.Empty;
@ -77,15 +77,6 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
ThrowIfFrozen();
this.location = startLocation;
}
#endregion
public override void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitPrimitiveType (this); visitor.VisitPrimitiveType (this);

10
ICSharpCode.NRefactory.CSharp/Ast/Statements/EmptyStatement.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary> /// <summary>
/// ; /// ;
/// </summary> /// </summary>
public class EmptyStatement : Statement, IRelocatable public class EmptyStatement : Statement
{ {
public TextLocation Location { public TextLocation Location {
get; get;
@ -48,14 +48,6 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
#region IRelocationable implementation
void IRelocatable.SetStartLocation (TextLocation startLocation)
{
ThrowIfFrozen();
this.Location = startLocation;
}
#endregion
public override void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitEmptyStatement (this); visitor.VisitEmptyStatement (this);

646
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs

File diff suppressed because it is too large Load Diff

120
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs

@ -365,7 +365,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{ {
var bracketStack = GetBracketStack (memberText); var bracketStack = GetBracketStack (memberText);
bool didAppendSemicolon = !appendSemicolon; bool didAppendSemicolon = !appendSemicolon;
char lastBracket = '\0'; //char lastBracket = '\0';
while (bracketStack.Count > 0) { while (bracketStack.Count > 0) {
var t = bracketStack.Pop (); var t = bracketStack.Pop ();
switch (t.Item1) { switch (t.Item1) {
@ -373,19 +373,19 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
wrapper.Append (')'); wrapper.Append (')');
if (appendSemicolon) if (appendSemicolon)
didAppendSemicolon = false; didAppendSemicolon = false;
lastBracket = ')'; //lastBracket = ')';
break; break;
case '[': case '[':
wrapper.Append (']'); wrapper.Append (']');
if (appendSemicolon) if (appendSemicolon)
didAppendSemicolon = false; didAppendSemicolon = false;
lastBracket = ']'; //lastBracket = ']';
break; break;
case '<': case '<':
wrapper.Append ('>'); wrapper.Append ('>');
if (appendSemicolon) if (appendSemicolon)
didAppendSemicolon = false; didAppendSemicolon = false;
lastBracket = '>'; //lastBracket = '>';
break; break;
case '{': case '{':
int o = t.Item2 - 1; int o = t.Item2 - 1;
@ -418,46 +418,62 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
protected CompilationUnit ParseStub (string continuation, bool appendSemicolon = true, string afterContinuation = null) protected CompilationUnit ParseStub (string continuation, bool appendSemicolon = true, string afterContinuation = null)
{ {
var mt = GetMemberTextToCaret (); var mt = GetMemberTextToCaret ();
if (mt == null) if (mt == null) {
return null; return null;
}
string memberText = mt.Item1; string memberText = mt.Item1;
bool wrapInClass = mt.Item2; var memberLocation = mt.Item2;
int closingBrackets = 1;
int generatedLines = 0;
var wrapper = new StringBuilder (); var wrapper = new StringBuilder ();
bool wrapInClass = memberLocation != new TextLocation (1, 1);
if (wrapInClass) { if (wrapInClass) {
/* foreach (var child in Unit.Children) { var nodeAtLocation = Unit.GetNodeAt (memberLocation, n => n is TypeDeclaration || n is NamespaceDeclaration);
if (child is UsingDeclaration) { if (nodeAtLocation != null) {
var offset = document.GetOffset (child.StartLocation); foreach (var n in nodeAtLocation.AncestorsAndSelf) {
wrapper.Append (document.GetText (offset, document.GetOffset (child.EndLocation) - offset)); if (memberLocation == n.StartLocation) {
continue;
}
if (n is TypeDeclaration) {
var t = (TypeDeclaration)n;
switch (t.ClassType) {
case ClassType.Class:
wrapper.Append ("class");
break;
case ClassType.Struct:
wrapper.Append ("struct");
break;
case ClassType.Interface:
wrapper.Append ("interface");
break;
case ClassType.Enum:
wrapper.Append ("enum");
break;
} }
}*/ wrapper.Append (" " + t.Name + " {");
wrapper.Append ("class Stub {");
wrapper.AppendLine (); wrapper.AppendLine ();
closingBrackets++;
generatedLines++;
} else {
Console.WriteLine (n);
}
}
}
} }
wrapper.Append(memberText); wrapper.Append(memberText);
wrapper.Append(continuation); wrapper.Append(continuation);
AppendMissingClosingBrackets(wrapper, memberText, appendSemicolon); AppendMissingClosingBrackets(wrapper, memberText, appendSemicolon);
wrapper.Append(afterContinuation); wrapper.Append(afterContinuation);
if (wrapInClass) if (closingBrackets > 0) {
wrapper.Append ('}'); wrapper.Append(new string ('}', closingBrackets));
TextLocation memberLocation;
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
memberLocation = currentMember.Region.Begin;
} else if (currentType != null) {
memberLocation = currentType.Region.Begin;
} else {
memberLocation = new TextLocation (1, 1);
} }
using (var stream = new System.IO.StringReader (wrapper.ToString ())) { using (var stream = new System.IO.StringReader (wrapper.ToString ())) {
try { try {
var parser = new CSharpParser (); var parser = new CSharpParser ();
return parser.Parse (stream, "stub.cs", wrapInClass ? memberLocation.Line - 2 : 0); var result = parser.Parse(stream, "stub.cs", memberLocation.Line - 1 - generatedLines);
return result;
} catch (Exception) { } catch (Exception) {
Console.WriteLine("------"); Console.WriteLine("------");
Console.WriteLine(wrapper); Console.WriteLine(wrapper);
@ -473,26 +489,27 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
cachedText = null; cachedText = null;
} }
protected Tuple<string, bool> GetMemberTextToCaret () protected Tuple<string, TextLocation> GetMemberTextToCaret()
{ {
int startOffset; int startOffset;
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) { if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
startOffset = document.GetOffset (currentMember.Region.BeginLine, currentMember.Region.BeginColumn); startOffset = document.GetOffset(currentMember.Region.Begin);
} else if (currentType != null) { } else if (currentType != null) {
startOffset = document.GetOffset (currentType.Region.BeginLine, currentType.Region.BeginColumn); startOffset = document.GetOffset(currentType.Region.Begin);
} else { } else {
startOffset = 0; startOffset = 0;
} }
while (startOffset > 0) { while (startOffset > 0) {
char ch = document.GetCharAt(startOffset - 1); char ch = document.GetCharAt(startOffset - 1);
if (ch != ' ' && ch != '\t') if (ch != ' ' && ch != '\t') {
break; break;
}
--startOffset; --startOffset;
} }
if (cachedText == null) if (cachedText == null)
cachedText = document.GetText (startOffset, offset - startOffset); cachedText = document.GetText (startOffset, offset - startOffset);
return Tuple.Create (cachedText, startOffset != 0); return Tuple.Create (cachedText, document.GetLocation (startOffset));
} }
protected ExpressionResult GetInvocationBeforeCursor (bool afterBracket) protected ExpressionResult GetInvocationBeforeCursor (bool afterBracket)
@ -502,20 +519,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
baseUnit = ParseStub ("", false); baseUnit = ParseStub ("", false);
var section = baseUnit.GetNodeAt<AttributeSection> (location.Line, location.Column - 2); var section = baseUnit.GetNodeAt<AttributeSection> (location.Line, location.Column - 2);
var attr = section != null ? section.Attributes.LastOrDefault () : null; var attr = section != null ? section.Attributes.LastOrDefault () : null;
if (attr != null) { if (attr != null)
// insert target type into compilation unit, to respect the return new ExpressionResult ((AstNode)attr, baseUnit);
attr.Remove ();
var node = Unit.GetNodeAt (location) ?? Unit;
node.AddChild (attr, Roles.Attribute);
return new ExpressionResult ((AstNode)attr, Unit);
}
} }
if (currentMember == null && currentType == null) { if (currentMember == null && currentType == null) {
return null; return null;
} }
baseUnit = ParseStub (afterBracket ? "" : "x"); baseUnit = ParseStub (afterBracket ? "" : "x");
var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
var mref = baseUnit.GetNodeAt (location.Line, location.Column - 1, n => n is InvocationExpression || n is ObjectCreateExpression); var mref = baseUnit.GetNodeAt (location.Line, location.Column - 1, n => n is InvocationExpression || n is ObjectCreateExpression);
AstNode expr = null; AstNode expr = null;
if (mref is InvocationExpression) { if (mref is InvocationExpression) {
@ -533,11 +545,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (expr == null) if (expr == null)
return null; return null;
} }
var member = Unit.GetNodeAt<EntityDeclaration> (memberLocation); return new ExpressionResult ((AstNode)expr, baseUnit);
var member2 = baseUnit.GetNodeAt<EntityDeclaration> (memberLocation);
member2.Remove ();
member.ReplaceWith (member2);
return new ExpressionResult ((AstNode)expr, Unit);
} }
public class ExpressionResult public class ExpressionResult
@ -565,8 +573,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr, CompilationUnit unit) protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr, CompilationUnit unit)
{ {
if (expr == null) if (expr == null) {
return null; return null;
}
AstNode resolveNode; AstNode resolveNode;
if (expr is Expression || expr is AstType) { if (expr is Expression || expr is AstType) {
resolveNode = expr; resolveNode = expr;
@ -576,21 +585,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
resolveNode = expr; resolveNode = expr;
} }
try { try {
var csResolver = new CSharpAstResolver (GetState (), unit, CSharpParsedFile); var ctx = CSharpParsedFile.GetResolver(Compilation, location);
var root = expr.AncestorsAndSelf.FirstOrDefault(n => n is EntityDeclaration || n is CompilationUnit);
if (root == null) {
return null;
}
var csResolver = new CSharpAstResolver (ctx, root, CSharpParsedFile);
var result = csResolver.Resolve(resolveNode); var result = csResolver.Resolve(resolveNode);
var state = csResolver.GetResolverStateBefore(resolveNode); var state = csResolver.GetResolverStateBefore(resolveNode);
return Tuple.Create(result, state); return Tuple.Create(result, state);
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine(e);
return null; return null;
} }
} }
protected static void Print (AstNode node)
{
var v = new CSharpOutputVisitor (Console.Out, new CSharpFormattingOptions ());
node.AcceptVisitor (v);
}
#endregion #endregion
class DefaultMemberProvider : IMemberProvider class DefaultMemberProvider : IMemberProvider
@ -605,7 +614,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember) public void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember)
{ {
var document = engine.document; //var document = engine.document;
var location = engine.location; var location = engine.location;
currentType = null; currentType = null;
@ -659,7 +668,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
int startOffset = document.GetOffset (currentType.Region.Begin); int startOffset = document.GetOffset (currentType.Region.Begin);
int endOffset = document.GetOffset (location); int endOffset = document.GetOffset (location);
bool foundEndBracket = false; //bool foundEndBracket = false;
var bracketStack = new Stack<char> (); var bracketStack = new Stack<char> ();
@ -714,5 +723,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
} }
} }
} }

22
ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return null; return null;
baseUnit = ParseStub ("x] = a[1"); baseUnit = ParseStub ("x] = a[1");
var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
var mref = baseUnit.GetNodeAt (location, n => n is IndexerExpression); var mref = baseUnit.GetNodeAt (location, n => n is IndexerExpression);
AstNode expr; AstNode expr;
if (mref is IndexerExpression) { if (mref is IndexerExpression) {
@ -67,13 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return null; return null;
} }
var member = Unit.GetNodeAt<EntityDeclaration> (memberLocation); return new ExpressionResult ((AstNode)expr, baseUnit);
var member2 = baseUnit.GetNodeAt<EntityDeclaration> (memberLocation);
if (member == null || member2 == null)
return null;
member2.Remove ();
member.ReplaceWith (member2);
return new ExpressionResult ((AstNode)expr, Unit);
} }
public ExpressionResult GetConstructorInitializerBeforeCursor () public ExpressionResult GetConstructorInitializerBeforeCursor ()
@ -88,7 +82,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var expr = baseUnit.GetNodeAt <ConstructorInitializer> (location); var expr = baseUnit.GetNodeAt <ConstructorInitializer> (location);
if (expr == null) if (expr == null)
return null; return null;
return new ExpressionResult ((AstNode)expr, Unit); return new ExpressionResult ((AstNode)expr, baseUnit);
} }
public ExpressionResult GetTypeBeforeCursor () public ExpressionResult GetTypeBeforeCursor ()
@ -100,15 +94,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return null; return null;
baseUnit = ParseStub ("x> a"); baseUnit = ParseStub ("x> a");
var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
var expr = baseUnit.GetNodeAt<AstType> (location.Line, location.Column + 1); // '>' position var expr = baseUnit.GetNodeAt<AstType> (location.Line, location.Column + 1); // '>' position
var member = Unit.GetNodeAt<EntityDeclaration> (memberLocation); return new ExpressionResult ((AstNode)expr, baseUnit);
var member2 = baseUnit.GetNodeAt<EntityDeclaration> (memberLocation);
if (member == null || member2 == null)
return null;
member2.Remove ();
member.ReplaceWith (member2);
return new ExpressionResult ((AstNode)expr, Unit);
} }
IEnumerable<IMethod> CollectMethods (AstNode resolvedNode, MethodGroupResolveResult resolveResult) IEnumerable<IMethod> CollectMethods (AstNode resolvedNode, MethodGroupResolveResult resolveResult)

22
ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs

@ -129,12 +129,12 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public void ApplyChanges() public void ApplyChanges()
{ {
ApplyChanges(0, document.TextLength, document.Replace); ApplyChanges(0, document.TextLength, document.Replace, (o, l, v) => document.GetText(o, l) == v);
} }
public void ApplyChanges(int startOffset, int length) public void ApplyChanges(int startOffset, int length)
{ {
ApplyChanges(startOffset, length, document.Replace); ApplyChanges(startOffset, length, document.Replace, (o, l, v) => document.GetText(o, l) == v);
} }
/// <summary> /// <summary>
@ -150,11 +150,12 @@ namespace ICSharpCode.NRefactory.CSharp
ApplyChanges(startOffset, length, script.Replace); ApplyChanges(startOffset, length, script.Replace);
} }
public void ApplyChanges(int startOffset, int length, Action<int, int, string> documentReplace) public void ApplyChanges(int startOffset, int length, Action<int, int, string> documentReplace, Func<int, int, string, bool> filter = null)
{ {
int endOffset = startOffset + length; int endOffset = startOffset + length;
TextReplaceAction previousChange = null; TextReplaceAction previousChange = null;
int delta = 0; int delta = 0;
var depChanges = new List<TextReplaceAction> ();
foreach (var change in changes.OrderBy(c => c.Offset)) { foreach (var change in changes.OrderBy(c => c.Offset)) {
if (previousChange != null) { if (previousChange != null) {
if (change.Equals(previousChange)) { if (change.Equals(previousChange)) {
@ -174,16 +175,17 @@ namespace ICSharpCode.NRefactory.CSharp
} }
previousChange = change; previousChange = change;
if (change.Offset < startOffset) { bool skipChange = change.Offset < startOffset || change.Offset > endOffset;
// skip all changes in front of the begin offset skipChange |= filter != null && filter(change.Offset + delta, change.RemovalLength, change.NewText);
continue; skipChange &= !depChanges.Contains(change);
} else if (change.Offset > endOffset) {
// skip this change unless it depends on one that we already applied
continue;
}
if (!skipChange) {
documentReplace(change.Offset + delta, change.RemovalLength, change.NewText); documentReplace(change.Offset + delta, change.RemovalLength, change.NewText);
delta += change.NewText.Length - change.RemovalLength; delta += change.NewText.Length - change.RemovalLength;
if (change.DependsOn != null) {
depChanges.Add(change.DependsOn);
}
}
} }
changes.Clear(); changes.Clear();
} }

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

@ -126,7 +126,6 @@
<Compile Include="Ast\GeneralScope\UsingDeclaration.cs" /> <Compile Include="Ast\GeneralScope\UsingDeclaration.cs" />
<Compile Include="Ast\IAstVisitor.cs" /> <Compile Include="Ast\IAstVisitor.cs" />
<Compile Include="Ast\Identifier.cs" /> <Compile Include="Ast\Identifier.cs" />
<Compile Include="Ast\IRelocatable.cs" />
<Compile Include="Ast\MemberType.cs" /> <Compile Include="Ast\MemberType.cs" />
<Compile Include="Ast\Modifiers.cs" /> <Compile Include="Ast\Modifiers.cs" />
<Compile Include="Ast\NodeType.cs" /> <Compile Include="Ast\NodeType.cs" />

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

@ -717,7 +717,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitTypeDeclaration(TypeDeclaration typeDeclaration) CodeObject IAstVisitor<CodeObject>.VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{ {
bool isNestedType = typeStack.Count > 0; //bool isNestedType = typeStack.Count > 0;
CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name); CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name);
typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers); typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers);
typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes)); typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes));

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

@ -80,11 +80,13 @@ namespace ICSharpCode.NRefactory.CSharp
if (nspace.NS != null && !string.IsNullOrEmpty(nspace.NS.Name)) { if (nspace.NS != null && !string.IsNullOrEmpty(nspace.NS.Name)) {
nDecl = new NamespaceDeclaration (); nDecl = new NamespaceDeclaration ();
if (loc != null) if (loc != null) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [0])), Roles.NamespaceKeyword); nDecl.AddChild(new CSharpTokenNode (Convert(loc [0])), Roles.NamespaceKeyword);
}
ConvertNamespaceName(nspace.RealMemberName, nDecl); ConvertNamespaceName(nspace.RealMemberName, nDecl);
if (loc != null && loc.Count > 1) if (loc != null && loc.Count > 1) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [1])), Roles.LBrace); nDecl.AddChild(new CSharpTokenNode (Convert(loc [1])), Roles.LBrace);
}
AddToNamespace(nDecl); AddToNamespace(nDecl);
namespaceStack.Push(nDecl); namespaceStack.Push(nDecl);
} }
@ -105,7 +107,6 @@ namespace ICSharpCode.NRefactory.CSharp
subContainer.Accept(this); subContainer.Accept(this);
} }
} }
if (nDecl != null) { if (nDecl != null) {
AddAttributeSection (nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); AddAttributeSection (nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
if (loc != null && loc.Count > 2) if (loc != null && loc.Count > 2)
@ -351,11 +352,13 @@ namespace ICSharpCode.NRefactory.CSharp
if (nspace.NS != null && !string.IsNullOrEmpty(nspace.NS.Name)) { if (nspace.NS != null && !string.IsNullOrEmpty(nspace.NS.Name)) {
nDecl = new NamespaceDeclaration (); nDecl = new NamespaceDeclaration ();
if (loc != null) if (loc != null) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [0])), Roles.NamespaceKeyword); nDecl.AddChild(new CSharpTokenNode (Convert(loc [0])), Roles.NamespaceKeyword);
}
ConvertNamespaceName(nspace.RealMemberName, nDecl); ConvertNamespaceName(nspace.RealMemberName, nDecl);
if (loc != null && loc.Count > 1) if (loc != null && loc.Count > 1) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [1])), Roles.LBrace); nDecl.AddChild(new CSharpTokenNode (Convert(loc [1])), Roles.LBrace);
}
AddToNamespace(nDecl); AddToNamespace(nDecl);
namespaceStack.Push(nDecl); namespaceStack.Push(nDecl);
} }
@ -372,7 +375,6 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
if (nDecl != null) { if (nDecl != null) {
AddAttributeSection(nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole); AddAttributeSection(nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
if (loc != null && loc.Count > 2) if (loc != null && loc.Count > 2)
@ -3606,29 +3608,20 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public static void AdjustLineLocations (AstNode node, int lineModifier)
{
if (node is IRelocatable) {
((IRelocatable)node).SetStartLocation (new TextLocation (node.StartLocation.Line + lineModifier, node.StartLocation.Column));
}
foreach (var child in node.Children) {
AdjustLineLocations (child, lineModifier);
}
}
public CompilationUnit Parse(CompilerCompilationUnit top, string fileName, int lineModifier = 0) public CompilationUnit Parse(CompilerCompilationUnit top, string fileName, int lineModifier = 0)
{ {
if (top == null) if (top == null) {
return null; return null;
}
CSharpParser.ConversionVisitor conversionVisitor = new ConversionVisitor (GenerateTypeSystemMode, top.LocationsBag); CSharpParser.ConversionVisitor conversionVisitor = new ConversionVisitor (GenerateTypeSystemMode, top.LocationsBag);
top.ModuleCompiled.Accept(conversionVisitor); top.ModuleCompiled.Accept(conversionVisitor);
InsertComments(top, conversionVisitor); InsertComments(top, conversionVisitor);
if (CompilationUnitCallback != null) if (CompilationUnitCallback != null) {
CompilationUnitCallback(top); CompilationUnitCallback(top);
if (lineModifier != 0) }
AdjustLineLocations (conversionVisitor.Unit, lineModifier); if (top.LastYYValue is Mono.CSharp.Expression) {
if (top.LastYYValue is Mono.CSharp.Expression)
conversionVisitor.Unit.TopExpression = ((Mono.CSharp.Expression)top.LastYYValue).Accept(conversionVisitor) as AstNode; conversionVisitor.Unit.TopExpression = ((Mono.CSharp.Expression)top.LastYYValue).Accept(conversionVisitor) as AstNode;
}
conversionVisitor.Unit.FileName = fileName; conversionVisitor.Unit.FileName = fileName;
return conversionVisitor.Unit; return conversionVisitor.Unit;
} }
@ -3665,8 +3658,7 @@ namespace ICSharpCode.NRefactory.CSharp
var file = new SourceFile (fileName, fileName, 0); var file = new SourceFile (fileName, fileName, 0);
Location.Initialize (new List<SourceFile> (new [] { file })); Location.Initialize (new List<SourceFile> (new [] { file }));
var module = new ModuleContainer (ctx); var module = new ModuleContainer (ctx);
var driver = new Driver (ctx); var parser = Driver.Parse (reader, file, module, lineModifier);
var parser = Driver.Parse (reader, file, module);
var top = new CompilerCompilationUnit () { var top = new CompilerCompilationUnit () {
ModuleCompiled = module, ModuleCompiled = module,

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

@ -376,6 +376,9 @@ namespace Mono.CSharp
get { get {
return ref_line; return ref_line;
} }
set {
ref_line = value;
}
} }
// //
@ -1532,7 +1535,6 @@ namespace Mono.CSharp
#endif #endif
number_pos = 0; number_pos = 0;
var loc = Location; var loc = Location;
bool hasLeadingDot = c == '.';
if (c >= '0' && c <= '9'){ if (c >= '0' && c <= '9'){
if (c == '0'){ if (c == '0'){

3
ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs

@ -113,12 +113,13 @@ namespace Mono.CSharp
input.Close (); input.Close ();
} }
public static CSharpParser Parse (SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module) public static CSharpParser Parse(SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, int lineModifier = 0)
{ {
var file = new CompilationSourceFile (module, sourceFile); var file = new CompilationSourceFile (module, sourceFile);
module.AddTypeContainer(file); module.AddTypeContainer(file);
CSharpParser parser = new CSharpParser (reader, file); CSharpParser parser = new CSharpParser (reader, file);
parser.Lexer.Line += lineModifier;
parser.Lexer.sbag = new SpecialsBag (); parser.Lexer.sbag = new SpecialsBag ();
parser.parse (); parser.parse ();
return parser; return parser;

6
ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs

@ -2025,8 +2025,8 @@ namespace Mono.CSharp {
static int id; static int id;
public int ID = id++; public int ID = id++;
static int clone_id_counter; // static int clone_id_counter;
int clone_id; // int clone_id;
#endif #endif
// int assignable_slots; // int assignable_slots;
@ -2338,7 +2338,7 @@ namespace Mono.CSharp {
{ {
Block target = (Block) t; Block target = (Block) t;
#if DEBUG #if DEBUG
target.clone_id = clone_id_counter++; // target.clone_id = clone_id_counter++;
#endif #endif
clonectx.AddBlockMap (this, target); clonectx.AddBlockMap (this, target);

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

@ -1712,7 +1712,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
CSharpResolver oldResolver = resolver; CSharpResolver oldResolver = resolver;
List<IParameter> parameters = (hasParameterList || parameterDeclarations.Any()) ? new List<IParameter>() : null; List<IParameter> parameters = (hasParameterList || parameterDeclarations.Any()) ? new List<IParameter>() : null;
bool oldIsWithinLambdaExpression = resolver.IsWithinLambdaExpression; //bool oldIsWithinLambdaExpression = resolver.IsWithinLambdaExpression;
resolver = resolver.WithIsWithinLambdaExpression(true); resolver = resolver.WithIsWithinLambdaExpression(true);
foreach (var pd in parameterDeclarations) { foreach (var pd in parameterDeclarations) {
IType type = ResolveType(pd.Type); IType type = ResolveType(pd.Type);
@ -2626,7 +2626,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (string.IsNullOrEmpty(catchClause.VariableName)) { if (string.IsNullOrEmpty(catchClause.VariableName)) {
Scan(catchClause.Type); Scan(catchClause.Type);
} else { } else {
DomRegion region = MakeRegion(catchClause.VariableNameToken); //DomRegion region = MakeRegion(catchClause.VariableNameToken);
StoreCurrentState(catchClause.VariableNameToken); StoreCurrentState(catchClause.VariableNameToken);
IVariable v = MakeVariable(ResolveType(catchClause.Type), catchClause.VariableNameToken); IVariable v = MakeVariable(ResolveType(catchClause.Type), catchClause.VariableNameToken);
resolver = resolver.AddVariable(v); resolver = resolver.AddVariable(v);

26
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs

@ -219,6 +219,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
pctx = pctx.AddAssemblyReferences (new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore }); pctx = pctx.AddAssemblyReferences (new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
var compilationUnit = new CSharpParser ().Parse (parsedText, "program.cs"); var compilationUnit = new CSharpParser ().Parse (parsedText, "program.cs");
compilationUnit.Freeze ();
var parsedFile = compilationUnit.ToTypeSystem (); var parsedFile = compilationUnit.ToTypeSystem ();
pctx = pctx.UpdateProjectContent (null, parsedFile); pctx = pctx.UpdateProjectContent (null, parsedFile);
@ -4764,5 +4765,30 @@ class MainClass
Assert.IsNull (provider.Find ("IEnumerable"), "'IEnumerable' found."); Assert.IsNull (provider.Find ("IEnumerable"), "'IEnumerable' found.");
} }
/// <summary>
/// Bug 3957 - [New Resolver]Override completion doesn't work well for overloaded methods
/// </summary>
[Test()]
public void TestBug3957 ()
{
var provider = CreateProvider (
@"class A
{
public virtual void Method()
{}
public virtual void Method(int i)
{}
}
class B : A
{
$override $
}
");
Assert.AreEqual (2, provider.Data.Where (d => d.DisplayText == "Method").Count ());
}
} }
} }

1
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs

@ -271,6 +271,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
pctx = pctx.AddAssemblyReferences (new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore }); pctx = pctx.AddAssemblyReferences (new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
var compilationUnit = new CSharpParser ().Parse (parsedText, "program.cs"); var compilationUnit = new CSharpParser ().Parse (parsedText, "program.cs");
compilationUnit.Freeze ();
var parsedFile = compilationUnit.ToTypeSystem (); var parsedFile = compilationUnit.ToTypeSystem ();
pctx = pctx.UpdateProjectContent (null, parsedFile); pctx = pctx.UpdateProjectContent (null, parsedFile);

2
ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs

@ -120,7 +120,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
void CheckMissingTokens(AstNode node) void CheckMissingTokens(AstNode node)
{ {
if (node is IRelocatable) { if (node is CSharpTokenNode) {
Assert.IsNull(node.FirstChild, "Token nodes should not have children"); Assert.IsNull(node.FirstChild, "Token nodes should not have children");
} else { } else {
var prevNodeEnd = node.StartLocation; var prevNodeEnd = node.StartLocation;

Loading…
Cancel
Save