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

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

@ -12,7 +12,7 @@ namespace ICSharpCode.NRefactory @@ -12,7 +12,7 @@ namespace ICSharpCode.NRefactory
/// <summary>
/// A line/column position.
/// </summary>
public struct Location : IComparable<Location>
public struct Location : IComparable<Location>, IEquatable<Location>
{
public static readonly Location Empty = new Location(-1, -1);
@ -64,6 +64,11 @@ namespace ICSharpCode.NRefactory @@ -64,6 +64,11 @@ namespace ICSharpCode.NRefactory
return (Location)obj == this;
}
public bool Equals(Location other)
{
return this == other;
}
public static bool operator ==(Location a, Location b)
{
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) { @@ -2476,7 +2476,7 @@ out Statement stmt) {
#line 1205 "cs.ATG"
BlockStatement blockStmt = new BlockStatement();
blockStmt.StartLocation = t.EndLocation;
blockStmt.StartLocation = t.Location;
compilationUnit.BlockStart(blockStmt);
if (!ParseMethodBodies) lexer.SkipCurrentBlock(0);

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

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

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

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

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.IO;
using ICSharpCode.NRefactory.Ast;
using NUnit.Framework;
@ -51,6 +52,37 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -51,6 +52,37 @@ namespace ICSharpCode.NRefactory.Tests.Ast
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]
public void CSharpPropertyImplementingInterfaceTest()
{

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

@ -44,6 +44,64 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring @@ -44,6 +44,64 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
{
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

Loading…
Cancel
Save