Browse Source

Fixed SD2-1180: Changed event inserted at wrong position

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2062 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
0729800650
  1. 2
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Lexer.cs
  2. 7
      src/Libraries/NRefactory/Project/Src/Location.cs
  3. 2
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  4. 2
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  5. 2
      src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs
  6. 32
      src/Libraries/NRefactory/Test/Parser/TypeLevel/PropertyDeclarationTests.cs
  7. 58
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/NRefactoryCodeGenerator.cs

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

@ -825,7 +825,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
break; break;
case '}': case '}':
if (--braceCount < 0) { if (--braceCount < 0) {
curToken = new Token(Tokens.CloseCurlyBrace, Col, Line); curToken = new Token(Tokens.CloseCurlyBrace, Col - 1, Line);
return; return;
} }
break; break;

7
src/Libraries/NRefactory/Project/Src/Location.cs

@ -12,7 +12,7 @@ namespace ICSharpCode.NRefactory
/// <summary> /// <summary>
/// A line/column position. /// A line/column position.
/// </summary> /// </summary>
public struct Location : IComparable<Location> public struct Location : IComparable<Location>, IEquatable<Location>
{ {
public static readonly Location Empty = new Location(-1, -1); public static readonly Location Empty = new Location(-1, -1);
@ -64,6 +64,11 @@ namespace ICSharpCode.NRefactory
return (Location)obj == this; return (Location)obj == this;
} }
public bool Equals(Location other)
{
return this == other;
}
public static bool operator ==(Location a, Location b) public static bool operator ==(Location a, Location b)
{ {
return a.x == b.x && a.y == b.y; return a.x == b.x && a.y == b.y;

2
src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs

@ -2476,7 +2476,7 @@ out Statement stmt) {
#line 1205 "cs.ATG" #line 1205 "cs.ATG"
BlockStatement blockStmt = new BlockStatement(); BlockStatement blockStmt = new BlockStatement();
blockStmt.StartLocation = t.EndLocation; blockStmt.StartLocation = t.Location;
compilationUnit.BlockStart(blockStmt); compilationUnit.BlockStart(blockStmt);
if (!ParseMethodBodies) lexer.SkipCurrentBlock(0); if (!ParseMethodBodies) lexer.SkipCurrentBlock(0);

2
src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG

@ -1203,7 +1203,7 @@ VariableDeclarator<List<VariableDeclaration> fieldDeclaration>
Block<out Statement stmt> /* not BlockStatement because of EmbeddedStatement */ Block<out Statement stmt> /* not BlockStatement because of EmbeddedStatement */
= =
"{" (. BlockStatement blockStmt = new BlockStatement(); "{" (. BlockStatement blockStmt = new BlockStatement();
blockStmt.StartLocation = t.EndLocation; blockStmt.StartLocation = t.Location;
compilationUnit.BlockStart(blockStmt); compilationUnit.BlockStart(blockStmt);
if (!ParseMethodBodies) lexer.SkipCurrentBlock(0); if (!ParseMethodBodies) lexer.SkipCurrentBlock(0);
.) .)

2
src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs

@ -212,6 +212,7 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
"End Sub"); "End Sub");
} }
/*
[Test, Ignore("NRefactory cannot guess the anonymous method's return type")] [Test, Ignore("NRefactory cannot guess the anonymous method's return type")]
public void AnonymousMethodInVarDeclaration() public void AnonymousMethodInVarDeclaration()
{ {
@ -223,6 +224,7 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
"\tReturn argument * 2\n" + "\tReturn argument * 2\n" +
"End Function"); "End Function");
} }
*/
[Test] [Test]
public void RegisterEvent() public void RegisterEvent()

32
src/Libraries/NRefactory/Test/Parser/TypeLevel/PropertyDeclarationTests.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.IO;
using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast;
using NUnit.Framework; using NUnit.Framework;
@ -51,6 +52,37 @@ namespace ICSharpCode.NRefactory.Tests.Ast
Assert.IsTrue(pd.HasSetRegion); Assert.IsTrue(pd.HasSetRegion);
} }
void CSharpPropertyRegionTest(bool parseMethodBodies)
{
const string code = "class T {\n\tint Prop {\n\t\tget { return f; }\n\t\tset { f = value; }\n\t}\n}\n";
int line2Pos = code.IndexOf("\tint Prop");
int line3Pos = code.IndexOf("\t\tget");
int line4Pos = code.IndexOf("\t\tset");
IParser p = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(code));
p.ParseMethodBodies = parseMethodBodies;
p.Parse();
PropertyDeclaration pd = (PropertyDeclaration)p.CompilationUnit.Children[0].Children[0];
Assert.AreEqual(new Location(code.IndexOf("{\n\t\tget") - line2Pos + 1, 2), pd.BodyStart);
Assert.AreEqual(new Location(3, 5), pd.BodyEnd);
Assert.AreEqual(new Location(code.IndexOf("{ return") - line3Pos + 1, 3), pd.GetRegion.Block.StartLocation);
Assert.AreEqual(new Location(code.IndexOf("}\n\t\tset") + 1 - line3Pos + 1, 3), pd.GetRegion.Block.EndLocation);
Assert.AreEqual(new Location(code.IndexOf("{ f =") - line4Pos + 1, 4), pd.SetRegion.Block.StartLocation);
Assert.AreEqual(new Location(code.IndexOf("}\n\t}") + 1 - line4Pos + 1, 4), pd.SetRegion.Block.EndLocation);
}
[Test]
public void CSharpPropertyRegionTest()
{
CSharpPropertyRegionTest(true);
}
[Test]
public void CSharpPropertyRegionTestSkipParseMethodBodies()
{
CSharpPropertyRegionTest(false);
}
[Test] [Test]
public void CSharpPropertyImplementingInterfaceTest() public void CSharpPropertyImplementingInterfaceTest()
{ {

58
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/NRefactoryCodeGenerator.cs

@ -44,6 +44,64 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
{ {
return new CSharpOutputVisitor(); return new CSharpOutputVisitor();
} }
/// <summary>
/// Ensure that code is inserted correctly in {} code blocks - SD2-1180
/// </summary>
public override void InsertCodeAtEnd(DomRegion region, IDocument document, params AbstractNode[] nodes)
{
string beginLineIndentation = GetIndentation(document, region.BeginLine);
int insertionLine = region.EndLine - 1;
IDocumentLine endLine = document.GetLine(region.EndLine);
string endLineText = endLine.Text;
int originalPos = region.EndColumn - 2; // -1 for column coordinate => offset, -1 because EndColumn is after the '}'
int pos = originalPos;
if (pos >= endLineText.Length || endLineText[pos] != '}') {
LoggingService.Warn("CSharpCodeGenerator.InsertCodeAtEnd: position is invalid (not pointing to '}')"
+ " endLineText=" + endLineText + ", pos=" + pos);
} else {
for (pos--; pos >= 0; pos--) {
if (!char.IsWhiteSpace(endLineText[pos])) {
// range before '}' is not empty: we cannot simply insert in the line before the '}', so
//
pos++; // set pos to first whitespace character / the '{' character
if (pos < originalPos) {
// remove whitespace between last non-white character and the '}'
document.Remove(endLine.Offset + pos, originalPos - pos);
}
// insert newline and same indentation as used in beginLine before the '}'
document.Insert(endLine.Offset + pos, Environment.NewLine + beginLineIndentation);
insertionLine++;
pos = region.BeginColumn - 1;
if (region.BeginLine == region.EndLine && pos >= 1 && pos < endLineText.Length) {
// The whole block was in on a single line, e.g. "get { return field; }".
// Insert an additional newline after the '{'.
originalPos = pos = endLineText.IndexOf('{', pos);
if (pos >= 0 && pos < region.EndColumn - 1) {
// find next non-whitespace after originalPos
originalPos++; // point to insertion position for newline after {
for (pos++; pos < endLineText.Length; pos++) {
if (!char.IsWhiteSpace(endLineText[pos])) {
// remove all between originalPos and pos
if (originalPos < pos) {
document.Remove(endLine.Offset + originalPos, pos - originalPos);
}
document.Insert(endLine.Offset + originalPos, Environment.NewLine + beginLineIndentation + '\t');
insertionLine++;
break;
}
}
}
}
break;
}
}
}
InsertCodeAfter(insertionLine, document, beginLineIndentation + '\t', nodes);
}
} }
public class VBNetCodeGenerator : NRefactoryCodeGenerator public class VBNetCodeGenerator : NRefactoryCodeGenerator

Loading…
Cancel
Save