attributes>
(
"Sub"
Identifier (. name = t.val; .)
- "Lib" LiteralString (. library = t.val.ToString(); .)
- ["Alias" LiteralString (. alias = t.val.ToString(); .)]
+ "Lib" LiteralString (. library = t.literalValue.ToString(); .)
+ ["Alias" LiteralString (. alias = t.literalValue.ToString(); .)]
[ "(" [ FormalParameterList ] ")" ]
EOL
(.
@@ -1133,8 +1133,8 @@ StructureMemberDecl attributes>
|
"Function"
Identifier (. name = t.val; .)
- "Lib" LiteralString (. library = t.val; .)
- ["Alias" LiteralString (. alias = t.val; .)]
+ "Lib" LiteralString (. library = t.literalValue.ToString(); .)
+ ["Alias" LiteralString (. alias = t.literalValue.ToString(); .)]
[ "(" [ FormalParameterList ] ")" ]
["As" TypeName ]
EOL
diff --git a/src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToVBNetConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToVBNetConvertVisitor.cs
index 8aa4b18291..abf437c711 100644
--- a/src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToVBNetConvertVisitor.cs
+++ b/src/Libraries/NRefactory/Project/Src/Parser/Visitors/ToVBNetConvertVisitor.cs
@@ -13,6 +13,7 @@ using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
+using Attribute = ICSharpCode.NRefactory.Parser.AST.Attribute;
namespace ICSharpCode.NRefactory.Parser
{
@@ -146,5 +147,123 @@ namespace ICSharpCode.NRefactory.Parser
}
return base.Visit(assignmentExpression, data);
}
+
+ public override object Visit(MethodDeclaration methodDeclaration, object data)
+ {
+ if ((methodDeclaration.Modifier & Modifier.Visibility) == 0)
+ methodDeclaration.Modifier |= Modifier.Private;
+
+ base.Visit(methodDeclaration, data);
+
+ const Modifier externStatic = Modifier.Static | Modifier.Extern;
+ if ((methodDeclaration.Modifier & externStatic) == externStatic
+ && methodDeclaration.Body.IsNull)
+ {
+ foreach (AttributeSection sec in methodDeclaration.Attributes) {
+ foreach (Attribute att in sec.Attributes) {
+ if ("DllImport".Equals(att.Name, StringComparison.InvariantCultureIgnoreCase)) {
+ if (ConvertPInvoke(methodDeclaration, att)) {
+ sec.Attributes.Remove(att);
+ break;
+ }
+ }
+ }
+ if (sec.Attributes.Count == 0) {
+ methodDeclaration.Attributes.Remove(sec);
+ break;
+ }
+ }
+ }
+ return null;
+ }
+
+ bool ConvertPInvoke(MethodDeclaration method, ICSharpCode.NRefactory.Parser.AST.Attribute att)
+ {
+ if (att.PositionalArguments.Count != 1)
+ return false;
+ PrimitiveExpression pe = att.PositionalArguments[0] as PrimitiveExpression;
+ if (pe == null || !(pe.Value is string))
+ return false;
+ string libraryName = (string)pe.Value;
+ string alias = null;
+ bool setLastError = false;
+ bool exactSpelling = false;
+ CharsetModifier charSet = CharsetModifier.Auto;
+ foreach (NamedArgumentExpression arg in att.NamedArguments) {
+ switch (arg.Name) {
+ case "SetLastError":
+ pe = arg.Expression as PrimitiveExpression;
+ if (pe != null && pe.Value is bool)
+ setLastError = (bool)pe.Value;
+ else
+ return false;
+ break;
+ case "ExactSpelling":
+ pe = arg.Expression as PrimitiveExpression;
+ if (pe != null && pe.Value is bool)
+ exactSpelling = (bool)pe.Value;
+ else
+ return false;
+ break;
+ case "CharSet":
+ {
+ FieldReferenceExpression fre = arg.Expression as FieldReferenceExpression;
+ if (fre == null || !(fre.TargetObject is IdentifierExpression))
+ return false;
+ if ((fre.TargetObject as IdentifierExpression).Identifier != "CharSet")
+ return false;
+ switch (fre.FieldName) {
+ case "Unicode":
+ charSet = CharsetModifier.Unicode;
+ break;
+ case "Auto":
+ charSet = CharsetModifier.Auto;
+ break;
+ case "Ansi":
+ charSet = CharsetModifier.ANSI;
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ case "EntryPoint":
+ pe = arg.Expression as PrimitiveExpression;
+ if (pe != null)
+ alias = pe.Value as string;
+ break;
+ default:
+ return false;
+ }
+ }
+ if (setLastError && exactSpelling) {
+ // Only P/Invokes with SetLastError and ExactSpelling can be converted to a DeclareDeclaration
+ const Modifier removeModifiers = Modifier.Static | Modifier.Extern;
+ DeclareDeclaration decl = new DeclareDeclaration(method.Name, method.Modifier &~ removeModifiers,
+ method.TypeReference,
+ method.Parameters,
+ method.Attributes,
+ libraryName, alias, charSet);
+ ReplaceCurrentNode(decl);
+ base.Visit(decl, null);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public override object Visit(PropertyDeclaration propertyDeclaration, object data)
+ {
+ if ((propertyDeclaration.Modifier & Modifier.Visibility) == 0)
+ propertyDeclaration.Modifier |= Modifier.Private;
+ return base.Visit(propertyDeclaration, data);
+ }
+
+ public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
+ {
+ if ((constructorDeclaration.Modifier & Modifier.Visibility) == 0)
+ constructorDeclaration.Modifier |= Modifier.Private;
+ return base.Visit(constructorDeclaration, data);
+ }
}
}
diff --git a/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs
index 5a5fd8af3d..7d63318cf6 100644
--- a/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs
+++ b/src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetConstructsConvertVisitor.cs
@@ -14,6 +14,7 @@ using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.NRefactory.Parser.AST;
+using Attribute = ICSharpCode.NRefactory.Parser.AST.Attribute;
namespace ICSharpCode.NRefactory.Parser
{
@@ -24,12 +25,46 @@ namespace ICSharpCode.NRefactory.Parser
{
// The following conversions are implemented:
// MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this()
+ // Add Public Modifier to methods and properties
// The following conversions should be implemented in the future:
// Function A() \n A = SomeValue \n End Function -> convert to return statement
+ Dictionary usings;
+ List addedUsings;
+
+ public override object Visit(CompilationUnit compilationUnit, object data)
+ {
+ usings = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
+ addedUsings = new List();
+ base.Visit(compilationUnit, data);
+ int i;
+ for (i = 0; i < compilationUnit.Children.Count; i++) {
+ if (!(compilationUnit.Children[i] is UsingDeclaration))
+ break;
+ }
+ foreach (UsingDeclaration decl in addedUsings) {
+ decl.Parent = compilationUnit;
+ compilationUnit.Children.Insert(i++, decl);
+ }
+ usings = null;
+ addedUsings = null;
+ return null;
+ }
+
+ public override object Visit(Using @using, object data)
+ {
+ if (!@using.IsAlias) {
+ usings[@using.Name] = @using.Name;
+ }
+ return base.Visit(@using, data);
+ }
+
public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
{
+ if ((constructorDeclaration.Modifier & Modifier.Visibility) == 0)
+ constructorDeclaration.Modifier = Modifier.Public;
+
// MyBase.New() and MyClass.New() calls inside the constructor are converted to :base() and :this()
BlockStatement body = constructorDeclaration.Body;
if (body != null && body.Children.Count > 0) {
@@ -55,5 +90,82 @@ namespace ICSharpCode.NRefactory.Parser
}
return base.Visit(constructorDeclaration, data);
}
+
+ public override object Visit(DeclareDeclaration declareDeclaration, object data)
+ {
+ if (!usings.ContainsKey("System.Runtime.InteropServices")) {
+ UsingDeclaration @using = new UsingDeclaration("System.Runtime.InteropServices");
+ addedUsings.Add(@using);
+ base.Visit(@using, data);
+ }
+
+ MethodDeclaration method = new MethodDeclaration(declareDeclaration.Name, declareDeclaration.Modifier,
+ declareDeclaration.TypeReference, declareDeclaration.Parameters,
+ declareDeclaration.Attributes);
+ method.Modifier |= Modifier.Extern | Modifier.Static;
+ ICSharpCode.NRefactory.Parser.AST.Attribute att = new Attribute("DllImport", null, null);
+ att.PositionalArguments.Add(CreateStringLiteral(declareDeclaration.Library));
+ if (declareDeclaration.Alias.Length > 0) {
+ att.NamedArguments.Add(new NamedArgumentExpression("EntryPoint", CreateStringLiteral(declareDeclaration.Alias)));
+ }
+ switch (declareDeclaration.Charset) {
+ case CharsetModifier.Auto:
+ att.NamedArguments.Add(new NamedArgumentExpression("CharSet",
+ new FieldReferenceExpression(new IdentifierExpression("CharSet"),
+ "Auto")));
+ break;
+ case CharsetModifier.Unicode:
+ att.NamedArguments.Add(new NamedArgumentExpression("CharSet",
+ new FieldReferenceExpression(new IdentifierExpression("CharSet"),
+ "Unicode")));
+ break;
+ default:
+ att.NamedArguments.Add(new NamedArgumentExpression("CharSet",
+ new FieldReferenceExpression(new IdentifierExpression("CharSet"),
+ "Ansi")));
+ break;
+ }
+ att.NamedArguments.Add(new NamedArgumentExpression("SetLastError", new PrimitiveExpression(true, true.ToString())));
+ att.NamedArguments.Add(new NamedArgumentExpression("ExactSpelling", new PrimitiveExpression(true, true.ToString())));
+ AttributeSection sec = new AttributeSection(null, null);
+ sec.Attributes.Add(att);
+ method.Attributes.Add(sec);
+ ReplaceCurrentNode(method);
+ return base.Visit(method, data);
+ }
+
+ static PrimitiveExpression CreateStringLiteral(string text)
+ {
+ return new PrimitiveExpression(text, text);
+ }
+
+ public override object Visit(MethodDeclaration methodDeclaration, object data)
+ {
+ if ((methodDeclaration.Modifier & Modifier.Visibility) == 0)
+ methodDeclaration.Modifier |= Modifier.Public;
+
+ if ((methodDeclaration.Modifier & (Modifier.Static | Modifier.Extern)) == Modifier.Static
+ && methodDeclaration.Body.Children.Count == 0)
+ {
+ foreach (AttributeSection sec in methodDeclaration.Attributes) {
+ foreach (Attribute att in sec.Attributes) {
+ if ("DllImport".Equals(att.Name, StringComparison.InvariantCultureIgnoreCase)) {
+ methodDeclaration.Modifier |= Modifier.Extern;
+ methodDeclaration.Body = null;
+ }
+ }
+ }
+ }
+
+ return base.Visit(methodDeclaration, data);
+ }
+
+ public override object Visit(PropertyDeclaration propertyDeclaration, object data)
+ {
+ if ((propertyDeclaration.Modifier & Modifier.Visibility) == 0)
+ propertyDeclaration.Modifier = Modifier.Public;
+
+ return base.Visit(propertyDeclaration, data);
+ }
}
}
diff --git a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs
index e8937f6c7c..5d4f688961 100644
--- a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs
+++ b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs
@@ -31,8 +31,18 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
}
public void TestMember(string input, string expectedOutput)
+ {
+ TestMember(input, expectedOutput, null);
+ }
+
+ public void TestMember(string input, string expectedOutput, string expectedAutomaticImport)
{
StringBuilder b = new StringBuilder();
+ if (expectedAutomaticImport != null) {
+ b.Append("using ");
+ b.Append(expectedAutomaticImport);
+ b.AppendLine(";");
+ }
b.AppendLine("class tmp1");
b.AppendLine("{");
using (StringReader r = new StringReader(expectedOutput)) {
@@ -51,7 +61,7 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
StringBuilder b = new StringBuilder();
b.AppendLine("class tmp1");
b.AppendLine("{");
- b.AppendLine("\tvoid tmp2()");
+ b.AppendLine("\tpublic void tmp2()");
b.AppendLine("\t{");
using (StringReader r = new StringReader(expectedOutput)) {
string line;
@@ -89,5 +99,32 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
TestStatement("RaiseEvent someEvent(Me, EventArgs.Empty)",
"if (someEvent != null) {\n\tsomeEvent(this, EventArgs.Empty);\n}");
}
+
+ [Test]
+ public void StaticMethod()
+ {
+ TestMember("Shared Sub A()\nEnd Sub",
+ "public static void A()\n{\n}");
+ }
+
+ [Test]
+ public void PInvoke()
+ {
+ TestMember("Declare Function SendMessage Lib \"user32.dll\" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As UIntPtr, ByVal lParam As IntPtr) As IntPtr",
+ "[DllImport(\"user32.dll\", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]\n" +
+ "static extern IntPtr SendMessage(IntPtr hWnd, int Msg, UIntPtr wParam, IntPtr lParam);",
+ "System.Runtime.InteropServices");
+
+ TestMember("Declare Unicode Function SendMessage Lib \"user32.dll\" Alias \"SendMessageW\" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As UIntPtr, ByVal lParam As IntPtr) As IntPtr",
+ "[DllImport(\"user32.dll\", EntryPoint = \"SendMessageW\", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]\n" +
+ "static extern IntPtr SendMessage(IntPtr hWnd, int Msg, UIntPtr wParam, IntPtr lParam);",
+ "System.Runtime.InteropServices");
+
+ TestMember(" _\n" +
+ "Shared Function MessageBox(ByVal hwnd As IntPtr, ByVal t As String, ByVal caption As String, ByVal t2 As UInt32) As Integer\n" +
+ "End Function",
+ "[DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n" +
+ "public static extern int MessageBox(IntPtr hwnd, string t, string caption, UInt32 t2);");
+ }
}
}
diff --git a/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs b/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs
index ad2ccd1ab0..74827f7321 100644
--- a/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs
+++ b/src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs
@@ -49,7 +49,7 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
{
StringBuilder b = new StringBuilder();
b.AppendLine("Class tmp1");
- b.AppendLine("\tSub tmp2()");
+ b.AppendLine("\tPrivate Sub tmp2()");
using (StringReader r = new StringReader(expectedOutput)) {
string line;
while ((line = r.ReadLine()) != null) {
@@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
public void AnonymousMethod()
{
TestMember("void A() { someEvent += delegate(int argument) { return argument * 2; }; }",
- "Sub A()\n" +
+ "Private Sub A()\n" +
"\tAddHandler someEvent, AddressOf ConvertedAnonymousMethod1\n" +
"End Sub\n" +
"Private Sub ConvertedAnonymousMethod1(ByVal argument As Integer)\n" +
@@ -170,7 +170,7 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
public void AnonymousMethodInVarDeclaration()
{
TestMember("void A() { SomeDelegate i = delegate(int argument) { return argument * 2; }; }",
- "Sub A()\n" +
+ "Private Sub A()\n" +
"\tDim i As SomeDelegate = AddressOf ConvertedAnonymousMethod1\n" +
"End Sub\n" +
"Private Sub ConvertedAnonymousMethod1(ByVal argument As Integer)\n" +
@@ -190,5 +190,30 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
TestStatement("someEvent += new SomeDelegate(this.tmp2);",
"AddHandler someEvent, AddressOf tmp2");
}
+
+ [Test]
+ public void StaticMethod()
+ {
+ TestMember("static void A() {}",
+ "Private Shared Sub A()\nEnd Sub");
+ }
+
+ [Test]
+ public void PInvoke()
+ {
+ TestMember("[DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n" +
+ "public static extern int MessageBox(IntPtr hwnd, string t, string caption, UInt32 t2);",
+ " _\n" +
+ "Public Shared Function MessageBox(ByVal hwnd As IntPtr, ByVal t As String, ByVal caption As String, ByVal t2 As UInt32) As Integer\n" +
+ "End Function");
+
+ TestMember("[DllImport(\"user32.dll\", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]\n" +
+ "public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, UIntPtr wParam, IntPtr lParam);",
+ "Public Declare Ansi Function SendMessage Lib \"user32.dll\" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As UIntPtr, ByVal lParam As IntPtr) As IntPtr");
+
+ TestMember("[DllImport(\"user32.dll\", SetLastError = true, ExactSpelling = true, EntryPoint = \"SendMessageW\")]\n" +
+ "public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, UIntPtr wParam, IntPtr lParam);",
+ "Public Declare Auto Function SendMessage Lib \"user32.dll\" Alias \"SendMessageW\" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As UIntPtr, ByVal lParam As IntPtr) As IntPtr");
+ }
}
}
diff --git a/src/Libraries/NRefactory/Test/Parser/TypeLevel/DeclareDeclarationTests.cs b/src/Libraries/NRefactory/Test/Parser/TypeLevel/DeclareDeclarationTests.cs
index 4d3dcda918..8ab011d065 100644
--- a/src/Libraries/NRefactory/Test/Parser/TypeLevel/DeclareDeclarationTests.cs
+++ b/src/Libraries/NRefactory/Test/Parser/TypeLevel/DeclareDeclarationTests.cs
@@ -31,8 +31,8 @@ namespace ICSharpCode.NRefactory.Tests.AST
DeclareDeclaration dd = ParseUtilVBNet.ParseTypeMember(program);
Assert.AreEqual("System.Int32", dd.TypeReference.SystemType);
Assert.AreEqual("GetUserName", dd.Name);
- Assert.AreEqual("\"advapi32.dll\"", dd.Library);
- Assert.AreEqual("\"GetUserNameA\"", dd.Alias);
+ Assert.AreEqual("advapi32.dll", dd.Library);
+ Assert.AreEqual("GetUserNameA", dd.Alias);
Assert.AreEqual(CharsetModifier.ANSI, dd.Charset);
}
#endregion
diff --git a/src/Libraries/NRefactory/Test/Parser/TypeLevel/MethodDeclarationTests.cs b/src/Libraries/NRefactory/Test/Parser/TypeLevel/MethodDeclarationTests.cs
index d56bd44e40..e2c374c229 100644
--- a/src/Libraries/NRefactory/Test/Parser/TypeLevel/MethodDeclarationTests.cs
+++ b/src/Libraries/NRefactory/Test/Parser/TypeLevel/MethodDeclarationTests.cs
@@ -227,6 +227,7 @@ namespace ICSharpCode.NRefactory.Tests.AST
end sub";
MethodDeclaration md = ParseUtilVBNet.ParseTypeMember(program);
+ Assert.AreEqual(Modifier.Public | Modifier.Static, md.Modifier);
Assert.AreEqual(2, md.StartLocation.Y, "StartLocation.Y");
Assert.AreEqual(2, md.EndLocation.Y, "EndLocation.Y");
Assert.AreEqual(2, md.StartLocation.X, "StartLocation.X");
diff --git a/src/Main/Base/Project/Src/Dom/CodeCompletionOptions.cs b/src/Main/Base/Project/Src/Dom/CodeCompletionOptions.cs
index e49dbaedbe..9fcc6d07e5 100644
--- a/src/Main/Base/Project/Src/Dom/CodeCompletionOptions.cs
+++ b/src/Main/Base/Project/Src/Dom/CodeCompletionOptions.cs
@@ -43,7 +43,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public static int DataUsageCacheItemCount {
get {
- return properties.Get("DataUsageCacheItemCount", 200);
+ return properties.Get("DataUsageCacheItemCount", 500);
}
set {
properties.Set("DataUsageCacheItemCount", value);
diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/SharpDevelopAboutPanels.cs b/src/Main/Base/Project/Src/Gui/Dialogs/SharpDevelopAboutPanels.cs
index d1efbc91eb..50e552045e 100644
--- a/src/Main/Base/Project/Src/Gui/Dialogs/SharpDevelopAboutPanels.cs
+++ b/src/Main/Base/Project/Src/Gui/Dialogs/SharpDevelopAboutPanels.cs
@@ -71,6 +71,7 @@ namespace ICSharpCode.SharpDevelop.Gui
Dock = DockStyle.Fill;
throwExceptionButton.Location = new System.Drawing.Point(8, sponsorLabel.Bounds.Bottom + 1);
+ throwExceptionButton.AutoSize = true;
throwExceptionButton.Text = ResourceService.GetString("Dialog.About.ThrowExceptionButton");
throwExceptionButton.Size = new System.Drawing.Size(96, 24);
throwExceptionButton.Click += new EventHandler(ThrowExceptionButtonClick);
diff --git a/src/Main/Base/Project/Src/Project/MSBuildEngine.cs b/src/Main/Base/Project/Src/Project/MSBuildEngine.cs
index aac29d092f..c4f08a4699 100644
--- a/src/Main/Base/Project/Src/Project/MSBuildEngine.cs
+++ b/src/Main/Base/Project/Src/Project/MSBuildEngine.cs
@@ -301,9 +301,13 @@ namespace ICSharpCode.SharpDevelop.Project
if (string.Equals(file, activeTaskName, StringComparison.InvariantCultureIgnoreCase)) {
file = "";
} else {
+ bool isShortFileName = file == Path.GetFileNameWithoutExtension(file);
if (projectFiles.Count > 0) {
file = Path.Combine(Path.GetDirectoryName(projectFiles.Peek()), file);
}
+ if (isShortFileName && !File.Exists(file)) {
+ file = "";
+ }
}
CompilerError error = new CompilerError(file, lineNumber, columnNumber, code, message);
error.IsWarning = isWarning;