Browse Source

Fixed forum-7883: exception when converting "a += b" from C# to VB when "a" is a pointer type.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3120 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
fc91d0fdd7
  1. 4
      src/Libraries/NRefactory/Project/Src/Ast/Enums.cs
  2. 8
      src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs
  3. 4
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  4. 4
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  5. 2
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  6. 2
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  7. 4
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
  8. 6
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs
  9. 4
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs
  10. 16
      src/Libraries/NRefactory/Test/Output/SpecialOutputVisitorTest.cs
  11. 4
      src/Libraries/NRefactory/Test/Parser/Expressions/UnaryOperatorExpressionTests.cs
  12. 14
      src/Main/Base/Test/CodeConverterTests.cs
  13. 55
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs

4
src/Libraries/NRefactory/Project/Src/Ast/Enums.cs

@ -238,9 +238,9 @@ namespace ICSharpCode.NRefactory.Ast
PostDecrement, PostDecrement,
/// <summary>Dereferencing pointer</summary> /// <summary>Dereferencing pointer</summary>
Star, Dereference,
/// <summary>Get address of</summary> /// <summary>Get address of</summary>
BitWiseAnd AddressOf
} }
public enum ContinueType public enum ContinueType

8
src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs

@ -40,7 +40,9 @@ namespace ICSharpCode.NRefactory
if (arg.ToLowerInvariant().EndsWith(" then")) if (arg.ToLowerInvariant().EndsWith(" then"))
arg = arg.Substring(0, arg.Length - 5); arg = arg.Substring(0, arg.Length - 5);
} }
return new PreprocessingDirective(cmd, arg, dir.StartPosition, dir.EndPosition); return new PreprocessingDirective(cmd, arg, dir.StartPosition, dir.EndPosition) {
Expression = dir.Expression
};
} }
public static void CSharpToVB(List<ISpecial> list) public static void CSharpToVB(List<ISpecial> list)
@ -77,7 +79,9 @@ namespace ICSharpCode.NRefactory
if (cmd.Length > 1) { if (cmd.Length > 1) {
cmd = cmd.Substring(0, 2).ToUpperInvariant() + cmd.Substring(2); cmd = cmd.Substring(0, 2).ToUpperInvariant() + cmd.Substring(2);
} }
return new PreprocessingDirective(cmd, arg, dir.StartPosition, dir.EndPosition); return new PreprocessingDirective(cmd, arg, dir.StartPosition, dir.EndPosition) {
Expression = dir.Expression
};
} }
#endregion #endregion

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

@ -4245,7 +4245,7 @@ IsTypeCast()) {
lexer.NextToken(); lexer.NextToken();
#line 1766 "cs.ATG" #line 1766 "cs.ATG"
expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Star)); expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Dereference));
} else if (la.kind == 31) { } else if (la.kind == 31) {
lexer.NextToken(); lexer.NextToken();
@ -4260,7 +4260,7 @@ IsTypeCast()) {
lexer.NextToken(); lexer.NextToken();
#line 1769 "cs.ATG" #line 1769 "cs.ATG"
expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitWiseAnd)); expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.AddressOf));
} else { } else {
Expect(20); Expect(20);
Type( Type(

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

@ -1763,10 +1763,10 @@ UnaryExpr<out Expression uExpr>
| "-" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Minus)); .) | "-" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Minus)); .)
| "!" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Not)); .) | "!" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Not)); .)
| "~" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitNot)); .) | "~" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitNot)); .)
| "*" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Star)); .) | "*" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Dereference)); .)
| "++" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Increment)); .) | "++" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Increment)); .)
| "--" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Decrement)); .) | "--" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Decrement)); .)
| "&" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitWiseAnd)); .) | "&" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.AddressOf)); .)
/*--- cast expression: */ /*--- cast expression: */
/* Problem: "(" Type ")" from here and * /* Problem: "(" Type ")" from here and *

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

@ -4483,7 +4483,7 @@ out Expression uExpr) {
lexer.NextToken(); lexer.NextToken();
#line 1842 "VBNET.ATG" #line 1842 "VBNET.ATG"
uop = UnaryOperatorType.Star; isUOp = true; uop = UnaryOperatorType.Dereference; isUOp = true;
} }
} }
ExponentiationExpr( ExponentiationExpr(

2
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG

@ -1839,7 +1839,7 @@ UnaryExpr<out Expression uExpr>
.) = .) =
{ "+" (. uop = UnaryOperatorType.Plus; isUOp = true; .) { "+" (. uop = UnaryOperatorType.Plus; isUOp = true; .)
| "-" (. uop = UnaryOperatorType.Minus; isUOp = true; .) | "-" (. uop = UnaryOperatorType.Minus; isUOp = true; .)
| "*" (. uop = UnaryOperatorType.Star; isUOp = true;.) | "*" (. uop = UnaryOperatorType.Dereference; isUOp = true;.)
} }
ExponentiationExpr<out expr> ExponentiationExpr<out expr>
(. (.

4
src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

@ -2105,10 +2105,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
TrackVisit(unaryOperatorExpression.Expression, data); TrackVisit(unaryOperatorExpression.Expression, data);
outputFormatter.PrintToken(Tokens.Increment); outputFormatter.PrintToken(Tokens.Increment);
return null; return null;
case UnaryOperatorType.Star: case UnaryOperatorType.Dereference:
outputFormatter.PrintToken(Tokens.Times); outputFormatter.PrintToken(Tokens.Times);
break; break;
case UnaryOperatorType.BitWiseAnd: case UnaryOperatorType.AddressOf:
outputFormatter.PrintToken(Tokens.BitwiseAnd); outputFormatter.PrintToken(Tokens.BitwiseAnd);
break; break;
default: default:

6
src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs

@ -55,9 +55,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
if (IsInMemberBody if (IsInMemberBody
&& (string.Equals(directive.Cmd, "#Region", StringComparison.InvariantCultureIgnoreCase) && (string.Equals(directive.Cmd, "#Region", StringComparison.InvariantCultureIgnoreCase)
|| string.Equals(directive.Cmd, "#End", StringComparison.InvariantCultureIgnoreCase) || string.Equals(directive.Cmd, "#End", StringComparison.InvariantCultureIgnoreCase)
&& directive.Arg.ToLowerInvariant().StartsWith("region"))) && directive.Arg.StartsWith("Region", StringComparison.InvariantCultureIgnoreCase)))
{ {
WriteLineInPreviousLine("'" + directive.Cmd + " " + directive.Arg, forceWriteInPreviousBlock); WriteLineInPreviousLine("'" + directive.Cmd + " " + directive.Arg, forceWriteInPreviousBlock);
} else if (!directive.Expression.IsNull) {
VBNetOutputVisitor visitor = new VBNetOutputVisitor();
directive.Expression.AcceptVisitor(visitor, null);
WriteLineInPreviousLine(directive.Cmd + " " + visitor.Text + " Then", forceWriteInPreviousBlock);
} else { } else {
base.PrintPreprocessingDirective(directive, forceWriteInPreviousBlock); base.PrintPreprocessingDirective(directive, forceWriteInPreviousBlock);
} }

4
src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs

@ -2318,10 +2318,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.PrintText(" - 1)"); outputFormatter.PrintText(" - 1)");
return null; return null;
case UnaryOperatorType.Star: case UnaryOperatorType.Dereference:
outputFormatter.PrintToken(Tokens.Times); outputFormatter.PrintToken(Tokens.Times);
return null; return null;
case UnaryOperatorType.BitWiseAnd: case UnaryOperatorType.AddressOf:
outputFormatter.PrintToken(Tokens.AddressOf); outputFormatter.PrintToken(Tokens.AddressOf);
return null; return null;
default: default:

16
src/Libraries/NRefactory/Test/Output/SpecialOutputVisitorTest.cs

@ -229,6 +229,22 @@ End Class");
"#end if"); "#end if");
} }
[Test]
public void ConditionalCompilationCS2VB()
{
TestProgramCS2VB("class A\n" +
"{\n" +
" #if TEST\n" +
" public int Field;\n" +
" #endif\n" +
"}",
"Class A\n" +
" #If TEST Then\n" +
" Public Field As Integer\n" +
" #End If\n" +
"End Class");
}
[Test] [Test]
public void RegionInsideMethodCS2VB() public void RegionInsideMethodCS2VB()
{ {

4
src/Libraries/NRefactory/Test/Parser/Expressions/UnaryOperatorExpressionTests.cs

@ -76,13 +76,13 @@ namespace ICSharpCode.NRefactory.Tests.Ast
[Test] [Test]
public void CSharpStarTest() public void CSharpStarTest()
{ {
CSharpTestUnaryOperatorExpressionTest("*a", UnaryOperatorType.Star); CSharpTestUnaryOperatorExpressionTest("*a", UnaryOperatorType.Dereference);
} }
[Test] [Test]
public void CSharpBitWiseAndTest() public void CSharpBitWiseAndTest()
{ {
CSharpTestUnaryOperatorExpressionTest("&a", UnaryOperatorType.BitWiseAnd); CSharpTestUnaryOperatorExpressionTest("&a", UnaryOperatorType.AddressOf);
} }
#endregion #endregion

14
src/Main/Base/Test/CodeConverterTests.cs

@ -468,6 +468,20 @@ namespace ICSharpCode.SharpDevelop.Tests
"a = c[2];"); "a = c[2];");
} }
[Test]
public void PointerUsage()
{
TestStatementsCS2VB("int a = 2;" +
"int* b = &a;" +
"*b += 40;" +
"Console.WriteLine(*b);",
"Dim a As Integer = 2\n" +
"Dim b As New Pointer(Of Integer)(a)\n" +
"b.Target += 40\n" +
"Console.WriteLine(b.Target)");
}
[Test] [Test]
public void RemoveImportDuplicatedByProjectLevelImport() public void RemoveImportDuplicatedByProjectLevelImport()
{ {

55
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs

@ -10,6 +10,7 @@ using System.Collections.Generic;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors; using ICSharpCode.NRefactory.Visitors;
using System.Runtime.InteropServices;
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{ {
@ -409,7 +410,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
} else if (rr != null && rr.ResolvedType != null) { } else if (rr != null && rr.ResolvedType != null) {
IClass c = rr.ResolvedType.GetUnderlyingClass(); IClass c = rr.ResolvedType.GetUnderlyingClass();
if (c.ClassType == ClassType.Delegate) { if (c != null && c.ClassType == ClassType.Delegate) {
InvocationExpression invocation = new InvocationExpression( InvocationExpression invocation = new InvocationExpression(
new MemberReferenceExpression( new MemberReferenceExpression(
new IdentifierExpression("Delegate"), new IdentifierExpression("Delegate"),
@ -445,5 +446,57 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
return null; return null;
} }
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
{
base.VisitUnaryOperatorExpression(unaryOperatorExpression, data);
switch (unaryOperatorExpression.Op) {
case UnaryOperatorType.Dereference:
ReplaceCurrentNode(new MemberReferenceExpression(unaryOperatorExpression.Expression, "Target") {
StartLocation = unaryOperatorExpression.StartLocation,
EndLocation = unaryOperatorExpression.EndLocation
});
break;
case UnaryOperatorType.AddressOf:
ResolveResult rr = resolver.ResolveInternal(unaryOperatorExpression.Expression, ExpressionContext.Default);
if (rr != null && rr.ResolvedType != null) {
TypeReference targetType = Refactoring.CodeGenerator.ConvertType(rr.ResolvedType, CreateContext());
TypeReference pointerType = new TypeReference("Pointer", new List<TypeReference> { targetType });
ReplaceCurrentNode(new ObjectCreateExpression(pointerType, new List<Expression> { unaryOperatorExpression.Expression }) {
StartLocation = unaryOperatorExpression.StartLocation,
EndLocation = unaryOperatorExpression.EndLocation
});
}
break;
}
return null;
}
public override object VisitTypeReference(TypeReference typeReference, object data)
{
while (typeReference.PointerNestingLevel > 0) {
TypeReference tr = new TypeReference(typeReference.Type, typeReference.SystemType) {
IsGlobal = typeReference.IsGlobal,
};
tr.GenericTypes.AddRange(typeReference.GenericTypes);
typeReference = new TypeReference("Pointer") {
StartLocation = typeReference.StartLocation,
EndLocation = typeReference.EndLocation,
PointerNestingLevel = typeReference.PointerNestingLevel - 1,
GenericTypes = { tr },
RankSpecifier = typeReference.RankSpecifier
};
}
ReplaceCurrentNode(typeReference);
return base.VisitTypeReference(typeReference, data);
}
public override object VisitUnsafeStatement(UnsafeStatement unsafeStatement, object data)
{
base.VisitUnsafeStatement(unsafeStatement, data);
ReplaceCurrentNode(unsafeStatement.Block);
return null;
}
} }
} }

Loading…
Cancel
Save