Browse Source

Fixed C# parser bug: cast followed by anonymous method.

Added "StringResourceToolAddIn" to src/Tools: little AddIn that helps adding resources to our internal translation database.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1009 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
fd3cc63664
  1. 18
      data/templates/project/CSharp/SharpDevelopMacro.xpt
  2. 2
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/KeywordList.txt
  3. 2
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Tokens.cs
  4. 502
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  5. 4
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  6. 4
      src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs
  7. 10
      src/Libraries/NRefactory/Test/Parser/Expressions/AnonymousMethodTests.cs
  8. 22
      src/Libraries/NRefactory/Test/Parser/Statements/BlockStatementTests.cs
  9. 19
      src/Tools/StringResourceTool/MainForm.cs
  10. 8
      src/Tools/StringResourceTool/StringResourceTool.sln
  11. 43
      src/Tools/StringResourceTool/TranslationServer.cs
  12. 27
      src/Tools/StringResourceToolAddIn/Configuration/AssemblyInfo.cs
  13. 69
      src/Tools/StringResourceToolAddIn/Src/Command.cs
  14. 20
      src/Tools/StringResourceToolAddIn/StringResourceToolAddIn.addin
  15. 64
      src/Tools/StringResourceToolAddIn/StringResourceToolAddIn.csproj

18
data/templates/project/CSharp/SharpDevelopMacro.xpt

@ -43,10 +43,8 @@ @@ -43,10 +43,8 @@
<Import assembly = "${ProjectName}.dll"/>
</Runtime>
<Path name = "/SharpDevelop/Workbench/MainMenu/Tools">
<Path name = "/Workspace/Tools">
<MenuItem id = "${ProjectName}Command1"
insertafter = "Separator1"
insertbefore = "Separator2"
label = "${ProjectName}"
class = "${ProjectName}.ToolCommand1"/>
</Path>
@ -63,7 +61,7 @@ using ICSharpCode.SharpDevelop.Gui; @@ -63,7 +61,7 @@ using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.TextEditor;
namespace Macro1
namespace ${ProjectName}
{
public class ToolCommand1 : AbstractMenuCommand
{
@ -78,6 +76,8 @@ namespace Macro1 @@ -78,6 +76,8 @@ namespace Macro1
}
// Get the active text area from the control:
TextArea textArea = tecp.TextEditorControl.ActiveTextAreaControl.TextArea;
if (!textArea.SelectionManager.HasSomethingSelected)
return;
// get the selected text:
string text = textArea.SelectionManager.SelectedText;
// reverse the text:
@ -85,9 +85,15 @@ namespace Macro1 @@ -85,9 +85,15 @@ namespace Macro1
for (int i = text.Length - 1; i >= 0; i--)
b.Append(text[i]);
string newText = b.ToString();
// ensure caret is at start of selection
textArea.Caret.Position = textArea.SelectionManager.SelectionCollection[0].StartPosition;
// deselect text
textArea.SelectionManager.ClearSelection();
// replace the selected text with the new text:
// Replace() takes the arguments: start offset to replace, length of the text to remove, new text
textArea.Document.Replace(textArea.Caret.Offset, text.Length, newText);
textArea.Document.Replace(textArea.Caret.Offset,
text.Length,
newText);
// Redraw:
textArea.Refresh();
}
@ -97,6 +103,8 @@ namespace Macro1 @@ -97,6 +103,8 @@ namespace Macro1
<File name="Configuration/AssemblyInfo.cs">
<![CDATA[${StandardHeader.C#}
using System.Reflection;
[assembly: AssemblyTitle("${ProjectName}")]
[assembly: AssemblyDescription("Macro AddIn for SharpDevelop 2.0")]
[assembly: AssemblyConfiguration("")]

2
src/Libraries/NRefactory/Project/Src/Lexer/CSharp/KeywordList.txt

@ -161,7 +161,7 @@ OverloadableBinaryOp("+", "-", "*", "/", "%", "&", "|", "^", "<<", "==", "!=", " @@ -161,7 +161,7 @@ OverloadableBinaryOp("+", "-", "*", "/", "%", "&", "|", "^", "<<", "==", "!=", "
TypeKW("char", "bool", "object", "string", "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "double", "decimal")
UnaryHead("+", "-", "!", "~", "*", "++", "--", "&")
AssnStartOp("+", "-", "!", "~", "*")
CastFollower(Identifier, Literal, "(", "new", "this", "base", "null", "checked", "unchecked", "typeof", "sizeof", @OverloadableUnaryOp)
CastFollower(Identifier, Literal, "(", "new", "this", "base", "null", "checked", "unchecked", "typeof", "sizeof", "delegate", @OverloadableUnaryOp)
AssgnOps("=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "<<=")
UnaryOp("+", "-", "!", "~", "*", "++", "--", "&")
TypeDeclarationKW("class", "interface", "struct", "enum", "delegate")

2
src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Tokens.cs

@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp @@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
public static BitArray TypeKW = NewSet(Char, Bool, Object, String, Sbyte, Byte, Short, Ushort, Int, Uint, Long, Ulong, Float, Double, Decimal);
public static BitArray UnaryHead = NewSet(Plus, Minus, Not, BitwiseComplement, Times, Increment, Decrement, BitwiseAnd);
public static BitArray AssnStartOp = NewSet(Plus, Minus, Not, BitwiseComplement, Times);
public static BitArray CastFollower = NewSet(Identifier, Literal, OpenParenthesis, New, This, Base, Null, Checked, Unchecked, Typeof, Sizeof, Plus, Not, BitwiseComplement, Increment, Decrement, True, False);
public static BitArray CastFollower = NewSet(Identifier, Literal, OpenParenthesis, New, This, Base, Null, Checked, Unchecked, Typeof, Sizeof, Delegate, Plus, Not, BitwiseComplement, Increment, Decrement, True, False);
public static BitArray AssgnOps = NewSet(Assign, PlusAssign, MinusAssign, TimesAssign, DivAssign, ModAssign, BitwiseAndAssign, BitwiseOrAssign, ShiftLeftAssign);
public static BitArray UnaryOp = NewSet(Plus, Minus, Not, BitwiseComplement, Times, Increment, Decrement, BitwiseAnd);
public static BitArray TypeDeclarationKW = NewSet(Class, Interface, Struct, Enum, Delegate);

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

File diff suppressed because it is too large Load Diff

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

@ -2093,9 +2093,7 @@ UnaryExpr<out Expression uExpr> @@ -2093,9 +2093,7 @@ UnaryExpr<out Expression uExpr>
/*--- cast expression: */
/* Problem: "(" Type ")" from here and *
* "(" Expr ")" from PrimaryExpr *
* are not distinguishable *
* Solution: (in IsTypeCast()) *
* use external information from compiled assembly or guess */
* Solution: (in IsTypeCast()) */
| IF (IsTypeCast()) "(" Type<out type> ")" (. expressions.Add(new CastExpression(type)); .)
)
}

4
src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs

@ -147,8 +147,8 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter @@ -147,8 +147,8 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
"End If");
// another bug related to the IfStatement code:
TestStatement("if (Tiles != null) foreach (Tile t in Tiles) this.TileTray.Controls.Remove(t);",
"If Tiles IsNot Nothing\n" +
"\tFor Each t As Tile in Tiles\n" +
"If Tiles IsNot Nothing Then\n" +
"\tFor Each t As Tile In Tiles\n" +
"\t\tMe.TileTray.Controls.Remove(t)\n" +
"\tNext\n" +
"End If");

10
src/Libraries/NRefactory/Test/Parser/Expressions/AnonymousMethodTests.cs

@ -29,6 +29,16 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -29,6 +29,16 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual(0, ame.Body.Children.Count);
}
[Test]
public void AnonymousMethodAfterCast()
{
CastExpression c = ParseUtilCSharp.ParseExpression<CastExpression>("(ThreadStart)delegate {}");
Assert.AreEqual("ThreadStart", c.CastTo.Type);
AnonymousMethodExpression ame = (AnonymousMethodExpression)c.Expression;
Assert.AreEqual(0, ame.Parameters.Count);
Assert.AreEqual(0, ame.Body.Children.Count);
}
[Test]
public void EmptyAnonymousMethod()
{

22
src/Libraries/NRefactory/Test/Parser/Statements/BlockStatementTests.cs

@ -22,10 +22,30 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -22,10 +22,30 @@ namespace ICSharpCode.NRefactory.Tests.AST
{
BlockStatement blockStmt = ParseUtilCSharp.ParseStatement<BlockStatement>("{}");
}
[Test]
public void CSharpComplexBlockStatementPositionTest()
{
string code = @"{
WebClient wc = new WebClient();
wc.Test();
wc.UploadStringCompleted += delegate {
output.BeginInvoke((MethodInvoker)delegate {
output.Text += newText;
});
};
}";
BlockStatement blockStmt = ParseUtilCSharp.ParseStatement<BlockStatement>(code);
//Assert.AreEqual(1, blockStmt.StartLocation.X); // does not work because ParseStatement inserts special code
Assert.AreEqual(1, blockStmt.StartLocation.Y);
Assert.AreEqual(2, blockStmt.EndLocation.X);
Assert.AreEqual(9, blockStmt.EndLocation.Y);
}
#endregion
#region VB.NET
// TODO
// TODO
#endregion
}
}

19
src/Tools/StringResourceTool/MainForm.cs

@ -37,6 +37,25 @@ namespace StringResourceTool @@ -37,6 +37,25 @@ namespace StringResourceTool
[STAThread]
public static void Main(string[] args)
{
if (args.Length == 3) {
try {
string userName, password;
using (StreamReader r = new StreamReader("password.txt")) {
userName = r.ReadLine();
password = r.ReadLine();
}
TranslationServer server = new TranslationServer(new TextBox());
if (!server.Login(userName, password)) {
MessageBox.Show("Login failed");
return;
}
server.AddResourceString(args[0], args[1], args[2]);
MessageBox.Show("Resource string added to database on server");
return;
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
}
}
Application.EnableVisualStyles();
Application.Run(new MainForm());
}

8
src/Tools/StringResourceTool/StringResourceTool.sln

@ -1,7 +1,9 @@ @@ -1,7 +1,9 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# SharpDevelop 2.0.0.689
# SharpDevelop 2.0.0.1006
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StringResourceTool", "StringResourceTool.csproj", "{197537EA-78F4-4434-904C-C81B19459FE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StringResourceToolAddIn", "..\StringResourceToolAddIn\StringResourceToolAddIn.csproj", "{3648E209-B853-4168-BFB5-7A60EAF316F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -12,5 +14,9 @@ Global @@ -12,5 +14,9 @@ Global
{197537EA-78F4-4434-904C-C81B19459FE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{197537EA-78F4-4434-904C-C81B19459FE7}.Release|Any CPU.Build.0 = Release|Any CPU
{197537EA-78F4-4434-904C-C81B19459FE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3648E209-B853-4168-BFB5-7A60EAF316F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3648E209-B853-4168-BFB5-7A60EAF316F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3648E209-B853-4168-BFB5-7A60EAF316F8}.Release|Any CPU.Build.0 = Release|Any CPU
{3648E209-B853-4168-BFB5-7A60EAF316F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
EndGlobal

43
src/Tools/StringResourceTool/TranslationServer.cs

@ -54,17 +54,17 @@ namespace StringResourceTool @@ -54,17 +54,17 @@ namespace StringResourceTool
WebClient wc = new WebClient();
wc.Headers.Set("Cookie", cookieContainer.GetCookieHeader(new Uri(baseURL)));
wc.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs e) {
output.BeginInvoke(new MethodInvoker(delegate {
output.Text = "Download: " + e.ProgressPercentage + "%";
}));
output.BeginInvoke((MethodInvoker)delegate {
output.Text = "Download: " + e.ProgressPercentage + "%";
});
};
wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) {
output.BeginInvoke(new MethodInvoker(delegate {
if (e.Error != null)
output.Text = e.Error.ToString();
else
output.Text = "Download complete.";
}));
output.BeginInvoke((MethodInvoker)delegate {
if (e.Error != null)
output.Text = e.Error.ToString();
else
output.Text = "Download complete.";
});
if (e.Error == null) {
using (FileStream fs = new FileStream(targetFile, FileMode.Create, FileAccess.Write)) {
fs.Write(e.Result, 0, e.Result.Length);
@ -76,6 +76,17 @@ namespace StringResourceTool @@ -76,6 +76,17 @@ namespace StringResourceTool
wc.DownloadDataAsync(new Uri(baseURL + "CompactNdownload.asp"));
}
public void AddResourceString(string idx, string value, string purpose)
{
WebClient wc = new WebClient();
wc.Headers.Set("Cookie", cookieContainer.GetCookieHeader(new Uri(baseURL)));
wc.Headers.Set("Content-Type", "application/x-www-form-urlencoded");
wc.UploadString(new Uri(baseURL + "owners_AddNew.asp"),
"Idx=" + Uri.EscapeDataString(idx)
+ "&PrimaryResLangValue=" + Uri.EscapeDataString(value)
+ "&PrimaryPurpose=" + Uri.EscapeDataString(purpose));
}
public void DeleteResourceStrings(string[] idx)
{
const int threadCount = 3; // 3 parallel calls
@ -90,10 +101,10 @@ namespace StringResourceTool @@ -90,10 +101,10 @@ namespace StringResourceTool
} else {
finishCount += 1;
if (finishCount == threadCount) {
output.BeginInvoke(new MethodInvoker(delegate {
output.Text += "\r\nFinished.";
output.Text += "\r\nYou have to re-download the database to see the changes.";
}));
output.BeginInvoke((MethodInvoker)delegate {
output.Text += "\r\nFinished.";
output.Text += "\r\nYou have to re-download the database to see the changes.";
});
}
}
}
@ -109,9 +120,9 @@ namespace StringResourceTool @@ -109,9 +120,9 @@ namespace StringResourceTool
wc.Headers.Set("Cookie", cookieContainer.GetCookieHeader(new Uri(baseURL)));
wc.Headers.Set("Content-Type", "application/x-www-form-urlencoded");
wc.UploadStringCompleted += delegate {
output.BeginInvoke(new MethodInvoker(delegate {
output.Text += "\r\nDeleted " + idx;
}));
output.BeginInvoke((MethodInvoker)delegate {
output.Text += "\r\nDeleted " + idx;
});
wc.Dispose();
if (callback != null)
callback(this, EventArgs.Empty);

27
src/Tools/StringResourceToolAddIn/Configuration/AssemblyInfo.cs

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
/*
* Created by SharpDevelop.
* User: Daniel Grunwald
* Date: 19.01.2006
* Time: 16:34
*/
using System.Reflection;
[assembly: AssemblyTitle("StringResourceToolAddIn")]
[assembly: AssemblyDescription("Macro AddIn for SharpDevelop 2.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SharpDevelop")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly: AssemblyVersion("1.0.*")]

69
src/Tools/StringResourceToolAddIn/Src/Command.cs

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
/*
* Created by SharpDevelop.
* User: Daniel Grunwald
* Date: 19.01.2006
* Time: 16:34
*/
using System;
using System.IO;
using System.Diagnostics;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.TextEditor;
namespace StringResourceToolAddIn
{
public class ToolCommand1 : AbstractMenuCommand
{
public override void Run()
{
// Here an example that shows how to access the current text document:
ITextEditorControlProvider tecp = WorkbenchSingleton.Workbench.ActiveContent as ITextEditorControlProvider;
if (tecp == null) {
// active content is not a text editor control
return;
}
// Get the active text area from the control:
TextArea textArea = tecp.TextEditorControl.ActiveTextAreaControl.TextArea;
if (!textArea.SelectionManager.HasSomethingSelected)
return;
// get the selected text:
string text = textArea.SelectionManager.SelectedText;
string resourceName = MessageService.ShowInputBox("Add Resource", "Enter the resource name", PropertyService.Get("ResourceToolLastResourceName"));
if (resourceName == null || resourceName.Length == 0) return;
PropertyService.Set("ResourceToolLastResourceName", resourceName);
string purpose = MessageService.ShowInputBox("Add Resource", "Enter resource purpose (may be empty)", "");
if (purpose == null) return;
string newText = "${res:" + resourceName + "}";
// ensure caret is at start of selection
textArea.Caret.Position = textArea.SelectionManager.SelectionCollection[0].StartPosition;
// deselect text
textArea.SelectionManager.ClearSelection();
// replace the selected text with the new text:
// Replace() takes the arguments: start offset to replace, length of the text to remove, new text
textArea.Document.Replace(textArea.Caret.Offset,
text.Length,
newText);
// Redraw:
textArea.Refresh();
string path = Path.Combine(FileUtility.ApplicationRootPath, "src/Tools/StringResourceTool/bin/Debug");
ProcessStartInfo info = new ProcessStartInfo(path + "/StringResourceTool.exe",
"\"" + resourceName + "\" "
+ "\"" + text + "\" "
+ "\"" + purpose + "\"");
info.WorkingDirectory = path;
Process.Start(info);
}
}
}

20
src/Tools/StringResourceToolAddIn/StringResourceToolAddIn.addin

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
<AddIn name = "StringResourceToolAddIn"
author = "Daniel Grunwald"
url = ""
description = "TODO: Put description here">
<Manifest>
<Identity name="ICSharpCode.Internal.StringResourceToolAddIn" version="@StringResourceToolAddIn.dll"/>
</Manifest>
<Runtime>
<Import assembly = "StringResourceToolAddIn.dll"/>
</Runtime>
<Path name = "/Workspace/Tools">
<MenuItem id = "StringResourceToolAddInCommand1"
label = "StringResourceToolAddIn"
shortcut = "Control|Shift|R"
class = "StringResourceToolAddIn.ToolCommand1"/>
</Path>
</AddIn>

64
src/Tools/StringResourceToolAddIn/StringResourceToolAddIn.csproj

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Library</OutputType>
<RootNamespace>StringResourceToolAddIn</RootNamespace>
<AssemblyName>StringResourceToolAddIn</AssemblyName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3648E209-B853-4168-BFB5-7A60EAF316F8}</ProjectGuid>
<OutputPath>..\..\..\AddIns\</OutputPath>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<Optimize>True</Optimize>
<DefineConstants>TRACE</DefineConstants>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="ICSharpCode.SharpDevelop">
<HintPath>..\..\..\bin\ICSharpCode.SharpDevelop.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.Core">
<HintPath>..\..\..\bin\ICSharpCode.Core.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.TextEditor">
<HintPath>..\..\..\bin\ICSharpCode.TextEditor.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="StringResourceToolAddIn.addin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Compile Include="Src\Command.cs" />
<Compile Include="Configuration\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>
Loading…
Cancel
Save