diff --git a/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs index f97d446dd2..c18d9f42ce 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs @@ -1989,6 +1989,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.PrintToken(Tokens.TimesAssign); break; case AssignmentOperatorType.Divide: + case AssignmentOperatorType.DivideInteger: outputFormatter.PrintToken(Tokens.DivAssign); break; case AssignmentOperatorType.ShiftLeft: diff --git a/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs index ee05bef1fc..b37c0da388 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs @@ -309,7 +309,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter VisitAttributes(typeDeclaration.Attributes, data); outputFormatter.Indent(); - OutputModifier(typeDeclaration.Modifier); + OutputModifier(typeDeclaration.Modifier, true); int typeToken = GetTypeToken(typeDeclaration); outputFormatter.PrintToken(typeToken); @@ -330,13 +330,17 @@ namespace ICSharpCode.NRefactory.PrettyPrinter } outputFormatter.NewLine(); + ++outputFormatter.IndentationLevel; if (typeDeclaration.BaseTypes != null && typeDeclaration.Type != ClassType.Enum) { foreach (TypeReference baseTypeRef in typeDeclaration.BaseTypes) { outputFormatter.Indent(); string baseType = baseTypeRef.Type; - bool baseTypeIsInterface = baseType.StartsWith("I") && (baseType.Length <= 1 || Char.IsUpper(baseType[1])); + if (baseType.IndexOf('.') >= 0) { + baseType = baseType.Substring(baseType.LastIndexOf('.') + 1); + } + bool baseTypeIsInterface = baseType.Length >= 2 && baseType[0] == 'I' && Char.IsUpper(baseType[1]); if (!baseTypeIsInterface || typeDeclaration.Type == ClassType.Interface) { outputFormatter.PrintToken(Tokens.Inherits); @@ -349,7 +353,6 @@ namespace ICSharpCode.NRefactory.PrettyPrinter } } - ++outputFormatter.IndentationLevel; TypeDeclaration oldType = currentType; currentType = typeDeclaration; @@ -409,7 +412,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter public object Visit(DelegateDeclaration delegateDeclaration, object data) { VisitAttributes(delegateDeclaration.Attributes, data); - OutputModifier(delegateDeclaration.Modifier); + OutputModifier(delegateDeclaration.Modifier, true); outputFormatter.PrintToken(Tokens.Delegate); outputFormatter.Space(); @@ -2040,6 +2043,16 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.Space(); nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data); return null; + case BinaryOperatorType.NullCoalescing: + outputFormatter.PrintText("IIf("); + nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data); + outputFormatter.PrintText(" Is Nothing, "); + nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data); + outputFormatter.PrintToken(Tokens.Comma); + outputFormatter.Space(); + nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data); + outputFormatter.PrintToken(Tokens.CloseParenthesis); + return null; case BinaryOperatorType.LessThan: op = Tokens.LessThan; break; @@ -2514,6 +2527,11 @@ namespace ICSharpCode.NRefactory.PrettyPrinter } void OutputModifier(Modifier modifier) + { + OutputModifier(modifier, false); + } + + void OutputModifier(Modifier modifier, bool forTypeDecl) { if ((modifier & Modifier.Public) == Modifier.Public) { outputFormatter.PrintToken(Tokens.Public); @@ -2543,7 +2561,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.Space(); } if ((modifier & Modifier.Abstract) == Modifier.Abstract) { - outputFormatter.PrintToken(Tokens.MustOverride); + outputFormatter.PrintToken(forTypeDecl ? Tokens.MustInherit : Tokens.MustOverride); outputFormatter.Space(); } if ((modifier & Modifier.Override) == Modifier.Override) { @@ -2558,7 +2576,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter } if ((modifier & Modifier.Sealed) == Modifier.Sealed) { - outputFormatter.PrintToken(Tokens.NotInheritable); + outputFormatter.PrintToken(forTypeDecl ? Tokens.NotInheritable : Tokens.NotOverridable); outputFormatter.Space(); } diff --git a/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs index 0512d3c653..0193e0c663 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs @@ -195,14 +195,43 @@ namespace ICSharpCode.NRefactory.Parser return base.Visit(methodDeclaration, data); } + public override object Visit(FieldDeclaration fieldDeclaration, object data) + { + fieldDeclaration.Modifier &= ~Modifier.Dim; // remove "Dim" flag + return base.Visit(fieldDeclaration, data); + } + public override object Visit(PropertyDeclaration propertyDeclaration, object data) { if ((propertyDeclaration.Modifier & Modifier.Visibility) == 0) propertyDeclaration.Modifier = Modifier.Public; + if (propertyDeclaration.HasSetRegion) { + propertyDeclaration.SetRegion.AcceptVisitor(new RenameIdentifierVisitor("Value", "value"), null); + } + return base.Visit(propertyDeclaration, data); } + class RenameIdentifierVisitor : AbstractAstVisitor + { + string from, to; + + public RenameIdentifierVisitor(string from, string to) + { + this.from = from; + this.to = to; + } + + public override object Visit(IdentifierExpression identifierExpression, object data) + { + if (string.Equals(identifierExpression.Identifier, from, StringComparison.InvariantCultureIgnoreCase)) { + identifierExpression.Identifier = to; + } + return base.Visit(identifierExpression, data); + } + } + static volatile Dictionary constantTable; static volatile Dictionary methodTable; diff --git a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs index 1d41a7394e..f571635126 100644 --- a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs +++ b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs @@ -146,6 +146,20 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "public object A {\n\tget {\n\t\treturn null;\n\t}\n}"); } + [Test] + public void ValueInPropertySetter() + { + TestMember("WriteOnly Property A()\nSet\nDim x As Object = Value\nEnd Set\nEnd Property", + "public object A {\n\tset {\n\t\tobject x = value;\n\t}\n}"); + } + + [Test] + public void FieldDeclaredWithDim() + { + TestMember("Dim f as String", + "string f;"); + } + [Test] public void PInvoke() { @@ -246,6 +260,15 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "x = \"Hello \" + \"World\";"); } + [Test] + public void IntegerDivision() + { + TestStatement(@"x = x \ b", + "x = x / b;"); + TestStatement(@"x \= b", + "x /= b;"); + } + [Test] public void VBConstants() { diff --git a/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs b/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs index 8ada95d169..ecd4cdc786 100644 --- a/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs +++ b/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs @@ -71,6 +71,42 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "End Namespace\r\n"); } + [Test] + public void ClassImplementsInterface() + { + TestProgram("class test : IComparable { }", + "Class test\r\n" + + "\tImplements IComparable\r\n" + + "End Class\r\n"); + } + + [Test] + public void ClassImplementsInterface2() + { + TestProgram("class test : System.IComparable { }", + "Class test\r\n" + + "\tImplements System.IComparable\r\n" + + "End Class\r\n"); + } + + [Test] + public void ClassInheritsClass() + { + TestProgram("class test : InvalidDataException { }", + "Class test\r\n" + + "\tInherits InvalidDataException\r\n" + + "End Class\r\n"); + } + + [Test] + public void ClassInheritsClass2() + { + TestProgram("class test : System.IO.InvalidDataException { }", + "Class test\r\n" + + "\tInherits System.IO.InvalidDataException\r\n" + + "End Class\r\n"); + } + [Test] public void ForWithUnknownConditionAndSingleStatement() { @@ -293,5 +329,12 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "\tNext\n" + "End Sub"); } + + [Test] + public void NullCoalescing() + { + TestStatement("c = a ?? b;", + "c = IIf(a Is Nothing, b, a)"); + } } } diff --git a/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs b/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs index 43a851457d..6191c856a7 100644 --- a/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs +++ b/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs @@ -78,6 +78,12 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter TestProgram("Public Partial Class Foo\nEnd Class"); } + [Test] + public void MustInheritClass() + { + TestProgram("Public MustInherit Class Foo\nEnd Class"); + } + [Test] public void GenericClassDefinition() { diff --git a/src/Main/Base/Project/Src/Dom/ClassFinder.cs b/src/Main/Base/Project/Src/Dom/ClassFinder.cs index b116af081c..c92a91628d 100644 --- a/src/Main/Base/Project/Src/Dom/ClassFinder.cs +++ b/src/Main/Base/Project/Src/Dom/ClassFinder.cs @@ -55,6 +55,8 @@ namespace ICSharpCode.SharpDevelop.Dom this.callingClass = callingClass; this.cu = callingClass.CompilationUnit; this.projectContent = cu.ProjectContent; + if (projectContent == null) + throw new ArgumentException("callingClass must have a project content!"); } // currently callingMember is not required @@ -78,6 +80,8 @@ namespace ICSharpCode.SharpDevelop.Dom } else { projectContent = ParserService.CurrentProjectContent; } + if (projectContent == null) + throw new ArgumentException("projectContent not found!"); } public IClass GetClass(string fullName, int typeParameterCount) diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs b/src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs index 5556be304c..da2a856952 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs @@ -376,7 +376,8 @@ namespace ICSharpCode.SharpDevelop.Gui public void SaveFile(FileDescriptionTemplate newfile, string content) { string parsedFileName = StringParser.Parse(newfile.Name); - string parsedContent = StringParser.Parse(content); + // Parse twice so that tags used in included standard header are parsed + string parsedContent = StringParser.Parse(StringParser.Parse(content)); if (parsedFileName.StartsWith("/") || parsedFileName.StartsWith("\\")) parsedFileName = parsedFileName.Substring(1); if (newfile.IsDependentFile && Path.IsPathRooted(parsedFileName)) { diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs index aa1da73484..99f10d265a 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs @@ -69,7 +69,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor { TextEditorDisplayBindingWrapper b2 = new TextEditorDisplayBindingWrapper(); - b2.textAreaControl.Document.TextContent = StringParser.Parse(content); + b2.textAreaControl.Document.TextContent = content; b2.textAreaControl.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy(language); b2.textAreaControl.InitializeFormatter(); b2.textAreaControl.ActivateQuickClassBrowserOnDemand();