diff --git a/src/Libraries/NRefactory/Project/Src/Ast/Enums.cs b/src/Libraries/NRefactory/Project/Src/Ast/Enums.cs index c6f4a9574d..7e19ab436f 100644 --- a/src/Libraries/NRefactory/Project/Src/Ast/Enums.cs +++ b/src/Libraries/NRefactory/Project/Src/Ast/Enums.cs @@ -238,9 +238,9 @@ namespace ICSharpCode.NRefactory.Ast PostDecrement, /// Dereferencing pointer - Star, + Dereference, /// Get address of - BitWiseAnd + AddressOf } public enum ContinueType diff --git a/src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs b/src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs index 36db0236c3..9baa88c6a8 100644 --- a/src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs +++ b/src/Libraries/NRefactory/Project/Src/Lexer/Special/PreProcessingDirective.cs @@ -40,7 +40,9 @@ namespace ICSharpCode.NRefactory if (arg.ToLowerInvariant().EndsWith(" then")) 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 list) @@ -77,7 +79,9 @@ namespace ICSharpCode.NRefactory if (cmd.Length > 1) { 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 diff --git a/src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs b/src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs index cbc268d499..f1f3d4a351 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs @@ -4245,7 +4245,7 @@ IsTypeCast()) { lexer.NextToken(); #line 1766 "cs.ATG" - expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Star)); + expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Dereference)); } else if (la.kind == 31) { lexer.NextToken(); @@ -4260,7 +4260,7 @@ IsTypeCast()) { lexer.NextToken(); #line 1769 "cs.ATG" - expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitWiseAnd)); + expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.AddressOf)); } else { Expect(20); Type( diff --git a/src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG b/src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG index d7a05a8eee..e2b7d9c6e9 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG +++ b/src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG @@ -1763,10 +1763,10 @@ UnaryExpr | "-" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Minus)); .) | "!" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Not)); .) | "~" (. 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.Decrement)); .) - | "&" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitWiseAnd)); .) + | "&" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.AddressOf)); .) /*--- cast expression: */ /* Problem: "(" Type ")" from here and * diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs index 355f3fb8e8..7062a9e086 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs @@ -4483,7 +4483,7 @@ out Expression uExpr) { lexer.NextToken(); #line 1842 "VBNET.ATG" - uop = UnaryOperatorType.Star; isUOp = true; + uop = UnaryOperatorType.Dereference; isUOp = true; } } ExponentiationExpr( diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG index 5fd7a62633..56d3caa4d7 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG @@ -1839,7 +1839,7 @@ UnaryExpr .) = { "+" (. uop = UnaryOperatorType.Plus; isUOp = true; .) | "-" (. uop = UnaryOperatorType.Minus; isUOp = true; .) - | "*" (. uop = UnaryOperatorType.Star; isUOp = true;.) + | "*" (. uop = UnaryOperatorType.Dereference; isUOp = true;.) } ExponentiationExpr (. diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs index 5b7a9d15db..f8930c77bc 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs @@ -2105,10 +2105,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter TrackVisit(unaryOperatorExpression.Expression, data); outputFormatter.PrintToken(Tokens.Increment); return null; - case UnaryOperatorType.Star: + case UnaryOperatorType.Dereference: outputFormatter.PrintToken(Tokens.Times); break; - case UnaryOperatorType.BitWiseAnd: + case UnaryOperatorType.AddressOf: outputFormatter.PrintToken(Tokens.BitwiseAnd); break; default: diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs index 9ee0c7943c..1fde6c26f5 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputFormatter.cs @@ -55,9 +55,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter if (IsInMemberBody && (string.Equals(directive.Cmd, "#Region", 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); + } else if (!directive.Expression.IsNull) { + VBNetOutputVisitor visitor = new VBNetOutputVisitor(); + directive.Expression.AcceptVisitor(visitor, null); + WriteLineInPreviousLine(directive.Cmd + " " + visitor.Text + " Then", forceWriteInPreviousBlock); } else { base.PrintPreprocessingDirective(directive, forceWriteInPreviousBlock); } diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs index 6e4c3e34e1..fef3450dc2 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs @@ -2318,10 +2318,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.PrintText(" - 1)"); return null; - case UnaryOperatorType.Star: + case UnaryOperatorType.Dereference: outputFormatter.PrintToken(Tokens.Times); return null; - case UnaryOperatorType.BitWiseAnd: + case UnaryOperatorType.AddressOf: outputFormatter.PrintToken(Tokens.AddressOf); return null; default: diff --git a/src/Libraries/NRefactory/Test/Output/SpecialOutputVisitorTest.cs b/src/Libraries/NRefactory/Test/Output/SpecialOutputVisitorTest.cs index 025700cbb5..627cd7f2ae 100644 --- a/src/Libraries/NRefactory/Test/Output/SpecialOutputVisitorTest.cs +++ b/src/Libraries/NRefactory/Test/Output/SpecialOutputVisitorTest.cs @@ -229,6 +229,22 @@ End Class"); "#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] public void RegionInsideMethodCS2VB() { diff --git a/src/Libraries/NRefactory/Test/Parser/Expressions/UnaryOperatorExpressionTests.cs b/src/Libraries/NRefactory/Test/Parser/Expressions/UnaryOperatorExpressionTests.cs index a97f099c9b..81b9bf4bad 100644 --- a/src/Libraries/NRefactory/Test/Parser/Expressions/UnaryOperatorExpressionTests.cs +++ b/src/Libraries/NRefactory/Test/Parser/Expressions/UnaryOperatorExpressionTests.cs @@ -76,13 +76,13 @@ namespace ICSharpCode.NRefactory.Tests.Ast [Test] public void CSharpStarTest() { - CSharpTestUnaryOperatorExpressionTest("*a", UnaryOperatorType.Star); + CSharpTestUnaryOperatorExpressionTest("*a", UnaryOperatorType.Dereference); } [Test] public void CSharpBitWiseAndTest() { - CSharpTestUnaryOperatorExpressionTest("&a", UnaryOperatorType.BitWiseAnd); + CSharpTestUnaryOperatorExpressionTest("&a", UnaryOperatorType.AddressOf); } #endregion diff --git a/src/Main/Base/Test/CodeConverterTests.cs b/src/Main/Base/Test/CodeConverterTests.cs index 934c1fafa0..42a13b6554 100644 --- a/src/Main/Base/Test/CodeConverterTests.cs +++ b/src/Main/Base/Test/CodeConverterTests.cs @@ -468,6 +468,20 @@ namespace ICSharpCode.SharpDevelop.Tests "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] public void RemoveImportDuplicatedByProjectLevelImport() { diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs index 1b491aaca6..97eb48bbd0 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Visitors; +using System.Runtime.InteropServices; namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver { @@ -409,7 +410,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver } } else if (rr != null && rr.ResolvedType != null) { IClass c = rr.ResolvedType.GetUnderlyingClass(); - if (c.ClassType == ClassType.Delegate) { + if (c != null && c.ClassType == ClassType.Delegate) { InvocationExpression invocation = new InvocationExpression( new MemberReferenceExpression( new IdentifierExpression("Delegate"), @@ -445,5 +446,57 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver } 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 { targetType }); + ReplaceCurrentNode(new ObjectCreateExpression(pointerType, new List { 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; + } } }