diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/VBNetProject.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/VBNetProject.cs index 49ad2e2e1c..5acf9830cc 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/VBNetProject.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Project/VBNetProject.cs @@ -26,15 +26,15 @@ namespace VBNetBinding switch (this.OutputType) { case OutputType.WinExe: SetProperty(e.Configuration, e.Platform, - "MyType", "WindowsForms", e.Location, true); + "MyType", "WindowsForms", e.NewLocation, true); break; case OutputType.Exe: SetProperty(e.Configuration, e.Platform, - "MyType", "Console", e.Location, true); + "MyType", "Console", e.NewLocation, true); break; default: SetProperty(e.Configuration, e.Platform, - "MyType", "Windows", e.Location, true); + "MyType", "Windows", e.NewLocation, true); break; } } diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs index d9457ce9f2..330e371fd8 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs @@ -223,28 +223,31 @@ namespace ICSharpCode.NRefactory.Visitors methodDeclaration.Body.Children.RemoveAt(methodDeclaration.Body.Children.Count - 1); methodDeclaration.Body.AddChild(rs); } else { - methodDeclaration.Body.AcceptVisitor(new ReturnStatementForFunctionAssignment(methodDeclaration.Name), null); - Expression init; - switch (methodDeclaration.TypeReference.SystemType) { - case "System.Int16": - case "System.Int32": - case "System.Int64": - case "System.Byte": - case "System.UInt16": - case "System.UInt32": - case "System.UInt64": - init = new PrimitiveExpression(0, "0"); - break; - case "System.Boolean": - init = new PrimitiveExpression(false, "false"); - break; - default: - init = new PrimitiveExpression(null, "null"); - break; + ReturnStatementForFunctionAssignment visitor = new ReturnStatementForFunctionAssignment(methodDeclaration.Name); + methodDeclaration.Body.AcceptVisitor(visitor, null); + if (visitor.replacementCount > 0) { + Expression init; + switch (methodDeclaration.TypeReference.SystemType) { + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.Byte": + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": + init = new PrimitiveExpression(0, "0"); + break; + case "System.Boolean": + init = new PrimitiveExpression(false, "false"); + break; + default: + init = new PrimitiveExpression(null, "null"); + break; + } + methodDeclaration.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, methodDeclaration.TypeReference))); + methodDeclaration.Body.Children[0].Parent = methodDeclaration.Body; + methodDeclaration.Body.AddChild(new ReturnStatement(new IdentifierExpression(FunctionReturnValueName))); } - methodDeclaration.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, methodDeclaration.TypeReference))); - methodDeclaration.Body.Children[0].Parent = methodDeclaration.Body; - methodDeclaration.Body.AddChild(new ReturnStatement(new IdentifierExpression(FunctionReturnValueName))); } } @@ -273,21 +276,22 @@ namespace ICSharpCode.NRefactory.Visitors class ReturnStatementForFunctionAssignment : AbstractAstTransformer { string functionName; + internal int replacementCount = 0; public ReturnStatementForFunctionAssignment(string functionName) { this.functionName = functionName; } - public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) + public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) { - IdentifierExpression ident = assignmentExpression.Left as IdentifierExpression; - if (ident != null) { - if (ident.Identifier.Equals(functionName, StringComparison.InvariantCultureIgnoreCase)) { - ident.Identifier = FunctionReturnValueName; + if (identifierExpression.Identifier.Equals(functionName, StringComparison.InvariantCultureIgnoreCase)) { + if (!(identifierExpression.Parent is AddressOfExpression) && !(identifierExpression.Parent is InvocationExpression)) { + identifierExpression.Identifier = FunctionReturnValueName; + replacementCount++; } } - return base.VisitAssignmentExpression(assignmentExpression, data); + return base.VisitIdentifierExpression(identifierExpression, data); } } #endregion diff --git a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs index 8353a486f8..c2ed261514 100644 --- a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs +++ b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs @@ -391,6 +391,18 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "}"); } + [Test] + public void FunctionWithoutImplicitReturn() + { + TestMember("Public Function run(i As Integer) As Integer\n" + + " Return 0\n" + + "End Function", + "public int run(int i)\n" + + "{\n" + + "\treturn 0;\n" + + "}"); + } + [Test] public void FunctionWithImplicitReturn() { @@ -421,6 +433,25 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "}"); } + [Test] + public void FunctionWithImplicitReturn2b() + { + const string ReturnValueName = VBNetConstructsConvertVisitor.FunctionReturnValueName; + TestMember("Public Function run(i As Integer) As Integer\n" + + " While something\n" + + " run = run + run(i - 1)\n" + + " End While\n" + + "End Function", + "public int run(int i)\n" + + "{\n" + + "\tint " + ReturnValueName + " = 0;\n" + + "\twhile (something) {\n" + + "\t\t" + ReturnValueName + " = " + ReturnValueName + " + run(i - 1);\n" + + "\t}\n" + + "\treturn " + ReturnValueName + ";\n" + + "}"); + } + [Test] public void FunctionWithImplicitReturn3() { diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 6a818ece7f..7187483694 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -24,7 +24,7 @@ False - DEBUG + DEBUG,TRACE True ..\..\..\..\bin\ 4 diff --git a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs index 7d0a5aebd8..b33dec8526 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs @@ -440,7 +440,9 @@ namespace ICSharpCode.SharpDevelop.Project lock (SyncRoot) { args = SetPropertyInternal(configuration, platform, propertyName, newValue, location, treatPropertyValueAsLiteral); } - OnPropertyChanged(args); + if (args.NewValue != args.OldValue || args.NewLocation != args.OldLocation) { + OnPropertyChanged(args); + } } ProjectPropertyChangedEventArgs SetPropertyInternal(string configuration, string platform, @@ -558,7 +560,11 @@ namespace ICSharpCode.SharpDevelop.Project args = new ProjectPropertyChangedEventArgs(propertyName); args.Configuration = configuration; args.Platform = platform; - args.Location = location; + args.NewLocation = location; + args.OldLocation = oldLocation; + if (newValue != null) { + args.NewValue = treatPropertyValueAsLiteral ? MSBuildInternals.Escape(newValue) : newValue; + } if (newValue == null) { if (existingPropertyGroup != null && existingProperty != null) { diff --git a/src/Main/Base/Project/Src/Project/ProjectPropertyChangedEventArgs.cs b/src/Main/Base/Project/Src/Project/ProjectPropertyChangedEventArgs.cs index aef054a7b6..23765785f5 100644 --- a/src/Main/Base/Project/Src/Project/ProjectPropertyChangedEventArgs.cs +++ b/src/Main/Base/Project/Src/Project/ProjectPropertyChangedEventArgs.cs @@ -15,8 +15,9 @@ namespace ICSharpCode.SharpDevelop.Project { string propertyName; string configuration, platform; - string oldValue; - PropertyStorageLocations location; + string oldValue, newValue; + PropertyStorageLocations newLocation; + PropertyStorageLocations oldLocation; public ProjectPropertyChangedEventArgs(string propertyName) { @@ -49,7 +50,7 @@ namespace ICSharpCode.SharpDevelop.Project } /// - /// Gets the old value before the property was changed. This value might not + /// Gets the (unevaluated) old value before the property was changed. This value might not /// be available if the property changed location. /// public string OldValue { @@ -57,12 +58,28 @@ namespace ICSharpCode.SharpDevelop.Project set { oldValue = value; } } + /// + /// The new (escaped) value of the property. + /// + public string NewValue { + get { return newValue; } + set { newValue = value; } + } + /// /// The location where the changed property was saved to. /// - public PropertyStorageLocations Location { - get { return location; } - set { location = value; } + public PropertyStorageLocations NewLocation { + get { return newLocation; } + set { newLocation = value; } + } + + /// + /// The location where the property was previously saved to. + /// + public PropertyStorageLocations OldLocation { + get { return oldLocation; } + set { oldLocation = value; } } } }