From 7eb5641bcf3558c3251c51b5458966dc6c3ded26 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 26 Jan 2013 18:49:58 +0100 Subject: [PATCH] add WPF designer back --- SharpDevelop.Tests.sln | 62 +- SharpDevelop.sln | 51 +- .../CSharpBinding/Project/CSharpBinding.addin | 1 + .../Project/CSharpBinding.csproj | 2 + .../Project/Src/Project/CSharpProject.cs | 11 + .../Src/Refactoring/CSharpCodeGenerator.cs | 93 +++ .../MoveTypeToFileContextAction.cs | 135 ++++ .../XamlBinding/XamlBinding/XamlResolver.cs | 52 +- .../Src/AbstractEventHandlerService.cs | 92 +-- .../Src/CSharpEventHandlerService.cs | 42 -- .../WpfDesign.AddIn/Src/FileUriContext.cs | 3 +- .../Src/IdeChooseClassService.cs | 32 +- .../WpfDesign.AddIn/Src/MyTypeFinder.cs | 31 +- .../Src/PropertyDescriptionService.cs | 6 +- .../WpfDesign.AddIn/Src/WpfDisplayBinding.cs | 9 +- .../WpfDesign.AddIn/Src/WpfViewContent.cs | 26 +- .../WpfDesign.AddIn/WpfDesign.AddIn.csproj | 18 +- .../WpfDesign/WpfDesign.AddIn/WpfDesign.addin | 1 - .../Project/WpfDesign.Designer.csproj | 5 +- .../IDesignerTypeResolutionService.cs | 18 + .../Project/Designer/TypeResolutionService.cs | 576 ++++++++++++++++++ .../Project/ICSharpCode.SharpDevelop.csproj | 14 +- .../{Src => }/Refactoring/ContextAction.cs | 0 .../Refactoring/EditorRefactoringContext.cs | 0 .../Project/Refactoring/ICodeGenerator.cs | 18 + .../{Src => }/Refactoring/IContextAction.cs | 0 .../Refactoring/IContextActionProvider.cs | 0 .../Src/Gui/Components/FontSelector.xaml.cs | 4 +- .../Project/Src/Project/AbstractProject.cs | 8 + src/Main/Base/Project/Src/Project/IProject.cs | 7 +- .../Project/Util/SharpDevelopExtensions.cs | 21 + 31 files changed, 1141 insertions(+), 197 deletions(-) create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeGenerator.cs create mode 100644 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs delete mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/CSharpEventHandlerService.cs create mode 100644 src/Main/Base/Project/Designer/IDesignerTypeResolutionService.cs create mode 100644 src/Main/Base/Project/Designer/TypeResolutionService.cs rename src/Main/Base/Project/{Src => }/Refactoring/ContextAction.cs (100%) rename src/Main/Base/Project/{Src => }/Refactoring/EditorRefactoringContext.cs (100%) create mode 100644 src/Main/Base/Project/Refactoring/ICodeGenerator.cs rename src/Main/Base/Project/{Src => }/Refactoring/IContextAction.cs (100%) rename src/Main/Base/Project/{Src => }/Refactoring/IContextActionProvider.cs (100%) diff --git a/SharpDevelop.Tests.sln b/SharpDevelop.Tests.sln index 0b419ed120..b2fab07c86 100644 --- a/SharpDevelop.Tests.sln +++ b/SharpDevelop.Tests.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.3 +# SharpDevelop 5.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}" ProjectSection(SolutionItems) = postProject EndProjectSection @@ -151,6 +151,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Data.EDMDesigne EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Data.SQLServer", "src\AddIns\DisplayBindings\Data\ICSharpCode.Data.SQLServer\ICSharpCode.Data.SQLServer.csproj", "{AFE34868-AFA1-4E1C-9450-47AB4BE329D5}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WpfDesign", "WpfDesign", "{83BAB756-1010-4A2F-9B9D-7F9EBCB288F5}" + ProjectSection(SolutionItems) = postProject + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.AddIn", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign.AddIn\WpfDesign.AddIn.csproj", "{9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Tests", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Tests\WpfDesign.Tests.csproj", "{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Designer", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj", "{78CC29AC-CC79-4355-B1F2-97936DF198AC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj", "{88DA149F-21B2-48AB-82C4-28FB6BDFD783}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{AF5E0DC1-1FA0-4346-A436-0C817C68F7C1}" ProjectSection(SolutionItems) = postProject EndProjectSection @@ -625,6 +639,46 @@ Global DC88D67C-E6B5-4994-9FA9-D4AB0E162FB3.Release|Any CPU.ActiveCfg = Release|Any CPU DC88D67C-E6B5-4994-9FA9-D4AB0E162FB3.Release|x86.Build.0 = Release|Any CPU DC88D67C-E6B5-4994-9FA9-D4AB0E162FB3.Release|x86.ActiveCfg = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|x86.Build.0 = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|x86.ActiveCfg = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|Any CPU.Build.0 = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|x86.Build.0 = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|x86.ActiveCfg = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|x86.Build.0 = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|x86.ActiveCfg = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|Any CPU.Build.0 = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|x86.Build.0 = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|x86.ActiveCfg = Release|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Debug|x86.Build.0 = Debug|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Debug|x86.ActiveCfg = Debug|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Release|Any CPU.Build.0 = Release|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Release|x86.Build.0 = Release|Any CPU + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Release|x86.ActiveCfg = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|x86.Build.0 = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|x86.ActiveCfg = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|Any CPU.Build.0 = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|x86.Build.0 = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|x86.ActiveCfg = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|x86.Build.0 = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|x86.ActiveCfg = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|Any CPU.Build.0 = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|x86.Build.0 = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|x86.ActiveCfg = Release|Any CPU {0B12A079-B2DB-42B9-8A8E-AA5CBC2B3225}.Debug|Any CPU.Build.0 = Debug|x86 {0B12A079-B2DB-42B9-8A8E-AA5CBC2B3225}.Debug|Any CPU.ActiveCfg = Debug|x86 {0B12A079-B2DB-42B9-8A8E-AA5CBC2B3225}.Debug|x86.Build.0 = Debug|x86 @@ -758,6 +812,12 @@ Global {5C70D6AB-0A33-43F9-B8B5-54558C35BBB1} = {0F5192F2-0744-4BA9-A074-6BE82D111B8D} {EEF5E054-4192-4A57-8FBF-E860D808A51D} = {0F5192F2-0744-4BA9-A074-6BE82D111B8D} {AFE34868-AFA1-4E1C-9450-47AB4BE329D5} = {0F5192F2-0744-4BA9-A074-6BE82D111B8D} + {83BAB756-1010-4A2F-9B9D-7F9EBCB288F5} = {11BF9245-88A3-4A0A-9A8A-EC9D98036B0F} + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F} = {83BAB756-1010-4A2F-9B9D-7F9EBCB288F5} + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865} = {83BAB756-1010-4A2F-9B9D-7F9EBCB288F5} + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1} = {83BAB756-1010-4A2F-9B9D-7F9EBCB288F5} + {78CC29AC-CC79-4355-B1F2-97936DF198AC} = {83BAB756-1010-4A2F-9B9D-7F9EBCB288F5} + {88DA149F-21B2-48AB-82C4-28FB6BDFD783} = {83BAB756-1010-4A2F-9B9D-7F9EBCB288F5} {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {AF5E0DC1-1FA0-4346-A436-0C817C68F7C1} {EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {AF5E0DC1-1FA0-4346-A436-0C817C68F7C1} {A4C858C8-51B6-4265-A695-A20FCEBA1D19} = {AF5E0DC1-1FA0-4346-A436-0C817C68F7C1} diff --git a/SharpDevelop.sln b/SharpDevelop.sln index 8ab3f56999..201fb12f0d 100644 --- a/SharpDevelop.sln +++ b/SharpDevelop.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -# SharpDevelop 4.3 +# SharpDevelop 5.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}" ProjectSection(SolutionItems) = postProject EndProjectSection @@ -137,6 +137,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Data.EDMDesigne EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Data.SQLServer", "src\AddIns\DisplayBindings\Data\ICSharpCode.Data.SQLServer\ICSharpCode.Data.SQLServer.csproj", "{AFE34868-AFA1-4E1C-9450-47AB4BE329D5}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WpfDesign", "WpfDesign", "{D54BEB89-8CBE-475C-8BB9-836D2FD71260}" + ProjectSection(SolutionItems) = postProject + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.AddIn", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign.AddIn\WpfDesign.AddIn.csproj", "{9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj", "{88DA149F-21B2-48AB-82C4-28FB6BDFD783}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Designer", "src\AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj", "{78CC29AC-CC79-4355-B1F2-97936DF198AC}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Analysis", "Analysis", "{7019F43E-DFD7-4D1C-8C96-E75D55646DE7}" ProjectSection(SolutionItems) = postProject EndProjectSection @@ -589,6 +601,38 @@ Global {AFE34868-AFA1-4E1C-9450-47AB4BE329D5}.Release|Any CPU.ActiveCfg = Release|Any CPU {AFE34868-AFA1-4E1C-9450-47AB4BE329D5}.Release|x86.Build.0 = Release|Any CPU {AFE34868-AFA1-4E1C-9450-47AB4BE329D5}.Release|x86.ActiveCfg = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|x86.Build.0 = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|x86.ActiveCfg = Debug|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|Any CPU.Build.0 = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|x86.Build.0 = Release|Any CPU + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|x86.ActiveCfg = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|x86.Build.0 = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Debug|x86.ActiveCfg = Debug|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|Any CPU.Build.0 = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|x86.Build.0 = Release|Any CPU + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}.Release|x86.ActiveCfg = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|x86.Build.0 = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Debug|x86.ActiveCfg = Debug|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|Any CPU.Build.0 = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|x86.Build.0 = Release|Any CPU + {88DA149F-21B2-48AB-82C4-28FB6BDFD783}.Release|x86.ActiveCfg = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|x86.Build.0 = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Debug|x86.ActiveCfg = Debug|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|Any CPU.Build.0 = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|x86.Build.0 = Release|Any CPU + {78CC29AC-CC79-4355-B1F2-97936DF198AC}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -650,6 +694,11 @@ Global {5C70D6AB-0A33-43F9-B8B5-54558C35BBB1} = {5FB020B2-B64B-4016-999A-CB8FD9274D72} {EEF5E054-4192-4A57-8FBF-E860D808A51D} = {5FB020B2-B64B-4016-999A-CB8FD9274D72} {AFE34868-AFA1-4E1C-9450-47AB4BE329D5} = {5FB020B2-B64B-4016-999A-CB8FD9274D72} + {D54BEB89-8CBE-475C-8BB9-836D2FD71260} = {11BF9245-88A3-4A0A-9A8A-EC9D98036B0F} + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F} = {D54BEB89-8CBE-475C-8BB9-836D2FD71260} + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865} = {D54BEB89-8CBE-475C-8BB9-836D2FD71260} + {88DA149F-21B2-48AB-82C4-28FB6BDFD783} = {D54BEB89-8CBE-475C-8BB9-836D2FD71260} + {78CC29AC-CC79-4355-B1F2-97936DF198AC} = {D54BEB89-8CBE-475C-8BB9-836D2FD71260} {1F261725-6318-4434-A1B1-6C70CE4CD324} = {7019F43E-DFD7-4D1C-8C96-E75D55646DE7} {3EAA45A9-735C-4AC7-A799-947B93EA449D} = {7019F43E-DFD7-4D1C-8C96-E75D55646DE7} 44FA68C9-DAD1-4C3C-90BB-3435F0D1D128 = {7019F43E-DFD7-4D1C-8C96-E75D55646DE7} diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin index 20e713efb8..81775855d4 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin @@ -279,5 +279,6 @@ + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj index dc46e7f09f..10c84081e3 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj @@ -74,6 +74,7 @@ + @@ -83,6 +84,7 @@ + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs index d53856cfbe..3ce7f73d09 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs @@ -4,6 +4,7 @@ using System; using System.CodeDom.Compiler; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -141,6 +142,16 @@ namespace CSharpBinding { return new CSharpCodeProvider(); } + + Refactoring.CSharpCodeGenerator generator; + + public override ICSharpCode.SharpDevelop.Refactoring.ICodeGenerator CodeGenerator { + get { + if (generator == null) + generator = new Refactoring.CSharpCodeGenerator(this); + return generator; + } + } } public class CSharpProjectBehavior : ProjectBehavior diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeGenerator.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeGenerator.cs new file mode 100644 index 0000000000..3f60bb043c --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeGenerator.cs @@ -0,0 +1,93 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Media.Animation; +using ICSharpCode.Core; +using ICSharpCode.Core.Presentation; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.NRefactory.CSharp.TypeSystem; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Refactoring; + +namespace CSharpBinding.Refactoring +{ + /// + /// Description of CSharpCodeGenerator. + /// + public class CSharpCodeGenerator : ICodeGenerator + { + CSharpProject project; + ProjectEntityModelContext model; + + public CSharpCodeGenerator(CSharpProject project) + { + if (project == null) + throw new ArgumentNullException("project"); + this.project = project; + this.model = new ProjectEntityModelContext(project, ".cs"); + } + + public void AddAttribute(IEntity target, IAttribute attribute) + { + var view = SD.FileService.OpenFile(new FileName(target.Region.FileName), false); + var editor = view.GetRequiredService(); + var context = SDRefactoringContext.Create(editor, CancellationToken.None); + var node = context.RootNode.GetNodeAt(target.Region.Begin); + var resolver = context.GetResolverStateBefore(node); + var builder = new TypeSystemAstBuilder(resolver); + + editor.Document.Insert(editor.Document.GetOffset(target.BodyRegion.Begin), + PrintAst(builder.ConvertAttribute(attribute))); + } + + public void InsertEventHandler(ITypeDefinition target, string name, IEvent eventDefinition, bool jumpTo) + { + IUnresolvedTypeDefinition match = null; + + foreach (var part in target.Parts) { + string fileName = part.UnresolvedFile.FileName; + if (!".cs".Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase)) + continue; + if (match == null || model.IsBetterPart(part, match)) + match = part; + } + + if (match == null) return; + + var view = SD.FileService.OpenFile(new FileName(match.Region.FileName), jumpTo); + var editor = view.GetRequiredService(); + var context = SDRefactoringContext.Create(editor, CancellationToken.None); + + IEntity last = (IEntity)target.GetMembers().LastOrDefault() ?? (IEntity)target; + var node = context.RootNode.GetNodeAt(last.Region.Begin); + var resolver = context.GetResolverStateAfter(node); + var builder = new TypeSystemAstBuilder(resolver); + + #warning implement code generation! + string eventHandler = ""; + + editor.Document.Insert(editor.Document.GetOffset(target.Region.End), eventHandler); + } + + string PrintAst(AstNode node) + { + StringBuilder sb = new StringBuilder(); + CSharpOutputVisitor visitor = new CSharpOutputVisitor(new StringWriter(sb), FormattingOptionsFactory.CreateSharpDevelop()); + node.AcceptVisitor(visitor); + return sb.ToString(); + } + } +} diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs new file mode 100644 index 0000000000..38e71724bd --- /dev/null +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs @@ -0,0 +1,135 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Linq; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using ICSharpCode.NRefactory.Editor; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Parser; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Refactoring; +using CSharpBinding.Parser; + +namespace CSharpBinding.Refactoring +{ + [ContextAction("Move type to file", Description = "Moves a selected type into a new file matching the type name.")] + public class MoveTypeToFileContextAction : ContextAction + { + public override async Task IsAvailableAsync(EditorRefactoringContext context, CancellationToken cancellationToken) + { + SyntaxTree st = await context.GetSyntaxTreeAsync().ConfigureAwait(false); + Identifier identifier = (Identifier)st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier); + if (identifier == null) return false; + if (MakeValidFileName(identifier.Name).Equals(Path.GetFileNameWithoutExtension(context.FileName), StringComparison.OrdinalIgnoreCase)) + return false; + if (identifier.Parent.Parent is TypeDeclaration) + return false; + ParseInformation info = await context.GetParseInformationAsync().ConfigureAwait(false); + if (info.UnresolvedFile.TopLevelTypeDefinitions.Count == 1) + return false; + return identifier.Parent is TypeDeclaration || identifier.Parent is DelegateDeclaration; + } + + public override async void Execute(EditorRefactoringContext context) + { + SyntaxTree st = await context.GetSyntaxTreeAsync().ConfigureAwait(false); + ICompilation compilation = await context.GetCompilationAsync().ConfigureAwait(false); + CSharpFullParseInformation info = await context.GetParseInformationAsync().ConfigureAwait(false) as CSharpFullParseInformation; + EntityDeclaration node = (EntityDeclaration)st.GetNodeAt(context.CaretLocation, n => n is TypeDeclaration || n is DelegateDeclaration); + IDocument document = context.Editor.Document; + + string newFileName = Path.Combine(Path.GetDirectoryName(context.FileName), MakeValidFileName(node.Name)); + string header = CopyFileHeader(document, info); + string footer = CopyFileEnd(document, info); + + AstNode newNode = node.Clone(); + + foreach (var ns in node.Ancestors.OfType()) { + var newNS = new NamespaceDeclaration(ns.Name); + newNS.Members.AddRange(ns.Children.Where(ch => ch is UsingDeclaration + || ch is UsingAliasDeclaration + || ch is ExternAliasDeclaration).Select(usingDecl => usingDecl.Clone())); + newNS.AddMember(newNode); + newNode = newNS; + } + + var topLevelUsings = st.Children.Where(ch => ch is UsingDeclaration + || ch is UsingAliasDeclaration + || ch is ExternAliasDeclaration); + StringBuilder newCode = new StringBuilder(header); + CSharpOutputVisitor visitor = new CSharpOutputVisitor(new StringWriter(newCode), FormattingOptionsFactory.CreateSharpDevelop()); + + foreach (var topLevelUsing in topLevelUsings) + topLevelUsing.AcceptVisitor(visitor); + + newNode.AcceptVisitor(visitor); + + newCode.AppendLine(footer); + + IViewContent viewContent = FileService.NewFile(newFileName, newCode.ToString()); + viewContent.PrimaryFile.SaveToDisk(newFileName); + // now that the code is saved in the other file, remove it from the original document + RemoveExtractedNode(); + + IProject project = (IProject)compilation.GetProject(); + if (project != null) { + FileProjectItem projectItem = new FileProjectItem(project, ItemType.Compile); + projectItem.FileName = newFileName; + ProjectService.AddProjectItem(project, projectItem); + FileService.FireFileCreated(newFileName, false); + project.Save(); + ProjectBrowserPad.RefreshViewAsync(); + } + } + + void RemoveExtractedNode() + { + //throw new NotImplementedException(); + } + + string CopyFileHeader(IDocument document, CSharpFullParseInformation info) + { + var lastHeadNode = info.SyntaxTree.Children + .TakeWhile(node => node.NodeType == NodeType.Whitespace && (!(node is Comment) || !((Comment)node).IsDocumentation)) + .LastOrDefault(); + if (lastHeadNode == null) + return ""; + return document.GetText(0, document.GetOffset(lastHeadNode.EndLocation)); + } + + string CopyFileEnd(IDocument document, CSharpFullParseInformation info) + { + var firstFootNode = info.SyntaxTree.Children.Reverse() + .TakeWhile(node => node.NodeType == NodeType.Whitespace && (!(node is Comment) || !((Comment)node).IsDocumentation)) + .LastOrDefault(); + if (firstFootNode == null) + return ""; + int offset = document.GetOffset(firstFootNode.StartLocation); + return document.GetText(offset, document.TextLength - offset); + } + + string MakeValidFileName(string name) + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.IndexOfAny(Path.GetInvalidFileNameChars()) > -1) + return name.RemoveAny(Path.GetInvalidFileNameChars()) + ".cs"; + return name + ".cs"; + } + + public override string DisplayName { + get { return "Move type to file"; } + } + } +} diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs index 6953832c73..40e14418e4 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlResolver.cs @@ -136,32 +136,36 @@ namespace ICSharpCode.XamlBinding ResolveResult ResolveAttributeValue(IMember propertyOrEvent, AXmlAttribute attribute) { - IType type = parseInfo.UnresolvedFile.GetTopLevelTypeDefinition(location).Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)); - if (propertyOrEvent is IEvent) { - var memberLookup = new MemberLookup(type.GetDefinition(), compilation.MainAssembly); - var rr = memberLookup.Lookup(new ThisResolveResult(type), attribute.Value, EmptyList.Instance, false); - if (rr is MethodGroupResolveResult) { - Conversion conversion = CSharpConversions.Get(compilation).ImplicitConversion(rr, propertyOrEvent.ReturnType); - IMethod method = conversion.Method; - if (method == null) - method = ((MethodGroupResolveResult)rr).Methods.FirstOrDefault(); - if (method != null) - return new MemberResolveResult(null, method); - } - return rr; - } else { - if (propertyOrEvent.Name == "Name") { - IField field = type.GetFields(f => f.Name == attribute.Value).FirstOrDefault(); - if (field != null) - return new MemberResolveResult(null, field); - } - if (propertyOrEvent.ReturnType.Kind == TypeKind.Enum) { - IField field = propertyOrEvent.ReturnType.GetFields(f => f.Name == attribute.Value).FirstOrDefault(); - if (field != null) - return new MemberResolveResult(null, field); + IUnresolvedTypeDefinition typeDefinition = parseInfo.UnresolvedFile.GetTopLevelTypeDefinition(location); + if (typeDefinition != null) { + IType type = typeDefinition.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)); + if (propertyOrEvent is IEvent) { + var memberLookup = new MemberLookup(type.GetDefinition(), compilation.MainAssembly); + var rr = memberLookup.Lookup(new ThisResolveResult(type), attribute.Value, EmptyList.Instance, false); + if (rr is MethodGroupResolveResult) { + Conversion conversion = CSharpConversions.Get(compilation).ImplicitConversion(rr, propertyOrEvent.ReturnType); + IMethod method = conversion.Method; + if (method == null) + method = ((MethodGroupResolveResult)rr).Methods.FirstOrDefault(); + if (method != null) + return new MemberResolveResult(null, method); + } + return rr; + } else { + if (propertyOrEvent.Name == "Name") { + IField field = type.GetFields(f => f.Name == attribute.Value).FirstOrDefault(); + if (field != null) + return new MemberResolveResult(null, field); + } + if (propertyOrEvent.ReturnType.Kind == TypeKind.Enum) { + IField field = propertyOrEvent.ReturnType.GetFields(f => f.Name == attribute.Value).FirstOrDefault(); + if (field != null) + return new MemberResolveResult(null, field); + } } + return new UnknownMemberResolveResult(type, attribute.Value, EmptyList.Instance); } - return new UnknownMemberResolveResult(type, attribute.Value, EmptyList.Instance); + return ErrorResolveResult.UnknownError; } ITypeReference CreateTypeReference(string @namespace, string localName) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/AbstractEventHandlerService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/AbstractEventHandlerService.cs index 8bdf697c40..9c74d39381 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/AbstractEventHandlerService.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/AbstractEventHandlerService.cs @@ -4,35 +4,32 @@ using System; using System.ComponentModel; using System.IO; +using System.Linq; using System.Windows.Controls; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.WpfDesign; namespace ICSharpCode.WpfDesign.AddIn { - abstract class AbstractEventHandlerService : IEventHandlerService + class SharpDevelopEventHandlerService : IEventHandlerService { WpfViewContent viewContent; - protected AbstractEventHandlerService(WpfViewContent viewContent) + public SharpDevelopEventHandlerService(WpfViewContent viewContent) { if (viewContent == null) throw new ArgumentNullException("viewContent"); this.viewContent = viewContent; } - protected IProjectContent GetProjectContent() - { - IProject p = FindProjectContainingFile(); - if (p != null) - return ParserService.GetProjectContent(p) ?? ParserService.DefaultProjectContent; - else - return ParserService.DefaultProjectContent; - } - IProject FindProjectContainingFile() { if (ProjectService.OpenSolution != null) { @@ -41,50 +38,48 @@ namespace ICSharpCode.WpfDesign.AddIn return null; } - protected IClass GetDesignedClass() + protected IType GetDesignedClass(ICompilation compilation) { - Designer.Xaml.XamlDesignContext xamlContext = viewContent.DesignContext as Designer.Xaml.XamlDesignContext; + var xamlContext = viewContent.DesignContext as Designer.Xaml.XamlDesignContext; if (xamlContext != null) { string className = xamlContext.ClassName; if (!string.IsNullOrEmpty(className)) { - return GetProjectContent().GetClass(className, 0); + return compilation.FindType(Type.GetType(className)); } } return null; } - protected IClass GetDesignedClassCodeBehindPart(IClass c) - { - CompoundClass compound = c as CompoundClass; - if (compound != null) { - c = null; - foreach (IClass part in compound.Parts) { - if (string.IsNullOrEmpty(part.CompilationUnit.FileName)) - continue; - if (".xaml".Equals(Path.GetExtension(part.CompilationUnit.FileName), StringComparison.OrdinalIgnoreCase)) - continue; - if (c == null || c.CompilationUnit.FileName.Length > part.CompilationUnit.FileName.Length) - c = part; - } - } - return c; - } - - protected abstract void CreateEventHandlerInternal(Type eventHandlerType, string handlerName); - public void CreateEventHandler(DesignItemProperty eventProperty) { - var item = eventProperty.DesignItem; - string handlerName = (string)eventProperty.ValueOnInstance; + string handlerName = (string)eventProperty.ValueOnInstance; if (string.IsNullOrEmpty(handlerName)) { + var item = eventProperty.DesignItem; if (string.IsNullOrEmpty(item.Name)) { GenerateName(eventProperty.DesignItem); } handlerName = item.Name + "_" + eventProperty.Name; eventProperty.SetValue(handlerName); } - CreateEventHandlerInternal(eventProperty.ReturnType, handlerName); + + IType t = GetDesignedClass(SD.ParserService.GetCompilation(FindProjectContainingFile())); + if (t != null) { + IMethod method = t.GetMethods(m => m.Name == handlerName).FirstOrDefault(); + if (method != null) { + FileService.JumpToFilePosition(method.Region.FileName, + method.Region.BeginLine, method.Region.BeginColumn); + return; + } + } + + IProject p = FindProjectContainingFile(); + ITypeDefinition c = t.GetDefinition(); + + if (p != null && c != null) { + var e = FindEventDeclaration(c.Compilation, eventProperty.DeclaringType, eventProperty.Name); + p.CodeGenerator.InsertEventHandler(c, handlerName, e, true); + } } public DesignItemProperty GetDefaultEvent(DesignItem item) @@ -93,21 +88,21 @@ namespace ICSharpCode.WpfDesign.AddIn if (attributes.Length == 1) { DefaultEventAttribute dae = (DefaultEventAttribute)attributes[0]; var events = TypeDescriptor.GetEvents(item.Component); - var eventInfo = events[dae.Name]; - if(eventInfo != null) - { - DesignItemProperty property = item.Properties.GetProperty(dae.Name); - if (property != null && property.IsEvent) - { - return property; - } - } + var eventInfo = events[dae.Name]; + if(eventInfo != null) + { + DesignItemProperty property = item.Properties.GetProperty(dae.Name); + if (property != null && property.IsEvent) + { + return property; + } + } } return null; } void GenerateName(DesignItem item) - { + { for (int i = 1;; i++) { try { string name = item.ComponentType.Name + i; @@ -118,5 +113,10 @@ namespace ICSharpCode.WpfDesign.AddIn } } } + + IEvent FindEventDeclaration(ICompilation compilation, Type declaringType, string name) + { + return compilation.FindType(declaringType).GetEvents(ue => ue.Name == name).FirstOrDefault(); + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/CSharpEventHandlerService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/CSharpEventHandlerService.cs deleted file mode 100644 index 4cba6086fc..0000000000 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/CSharpEventHandlerService.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Editor; - -namespace ICSharpCode.WpfDesign.AddIn -{ - sealed class CSharpEventHandlerService : AbstractEventHandlerService - { - public CSharpEventHandlerService(WpfViewContent viewContent) : base(viewContent) - { - } - - protected override void CreateEventHandlerInternal(Type eventHandlerType, string handlerName) - { - IClass c = GetDesignedClass(); - if (c != null) { - foreach (IMethod m in c.Methods) { - if (m.Name == handlerName) { - FileService.JumpToFilePosition(m.DeclaringType.CompilationUnit.FileName, - m.Region.BeginLine, m.Region.BeginColumn); - return; - } - } - } - c = GetDesignedClassCodeBehindPart(c); - if (c != null) { - ITextEditorProvider tecp = FileService.OpenFile(c.CompilationUnit.FileName) as ITextEditorProvider; - if (tecp != null) { - int lineNumber; - FormsDesigner.CSharpDesignerGenerator.CreateComponentEvent( - c, tecp.TextEditor, eventHandlerType, handlerName, null, - out lineNumber); - tecp.TextEditor.JumpTo(lineNumber, 0); - } - } - } - } -} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/FileUriContext.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/FileUriContext.cs index f6a6d02079..52a2df6aa7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/FileUriContext.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/FileUriContext.cs @@ -2,10 +2,9 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.IO; using System.Windows.Markup; -using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.WpfDesign.AddIn { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/IdeChooseClassService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/IdeChooseClassService.cs index 1c575877da..811bd784cf 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/IdeChooseClassService.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/IdeChooseClassService.cs @@ -2,13 +2,12 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Project; using System.Reflection; using System.Collections.Generic; using System.IO; -using ICSharpCode.Core; using ICSharpCode.WpfDesign.Designer.Services; namespace ICSharpCode.WpfDesign.AddIn @@ -16,37 +15,18 @@ namespace ICSharpCode.WpfDesign.AddIn //TODO public class IdeChooseClassService : ChooseClassServiceBase { - static string GetAssemblyPath(IProjectContent projectContent) - { - var r = projectContent as ReflectionProjectContent; - if (r != null) { - return r.RealAssemblyLocation; - } - var p = projectContent.Project as IProject; - if (p != null) { - return p.OutputAssemblyFullPath; - } - return null; - } - - static Assembly GetAssembly(IProjectContent projectContent) - { - var path = GetAssemblyPath(projectContent); - if (path != null && File.Exists(path)) { - return Assembly.LoadFile(path); - } - return null; - } - public override IEnumerable GetAssemblies() { - var pc = ParserService.CurrentProjectContent; + yield break; + #warning should load all assemblies available in the current project + /*var pc = ProjectService.CurrentProject; + if (pc == null) yield break; var a = GetAssembly(pc); if (a != null) yield return a; foreach (var r in pc.ThreadSafeGetReferencedContents()) { a = GetAssembly(r); if (a != null) yield return a; - } + } */ } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/MyTypeFinder.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/MyTypeFinder.cs index 82a6b0f8a8..7517a557b8 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/MyTypeFinder.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/MyTypeFinder.cs @@ -2,12 +2,16 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Linq; using System.Reflection; +using System.Runtime.ExceptionServices; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop.Workbench; using ICSharpCode.WpfDesign.XamlDom; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Project; -using TypeResolutionService = ICSharpCode.FormsDesigner.Services.TypeResolutionService; +using TypeResolutionService = ICSharpCode.SharpDevelop.Designer.TypeResolutionService; namespace ICSharpCode.WpfDesign.AddIn { @@ -27,9 +31,9 @@ namespace ICSharpCode.WpfDesign.AddIn public override Assembly LoadAssembly(string name) { if (string.IsNullOrEmpty(name)) { - IProjectContent pc = GetProjectContent(file); + IProject pc = GetProject(file); if (pc != null) { - return this.typeResolutionService.LoadAssembly(pc); + return typeResolutionService.LoadAssembly(pc); } return null; } else { @@ -43,19 +47,19 @@ namespace ICSharpCode.WpfDesign.AddIn Assembly FindAssemblyInProjectReferences(string name) { - IProjectContent pc = GetProjectContent(file); + IProject pc = GetProject(file); if (pc != null) { return FindAssemblyInProjectReferences(pc, name); } return null; } - Assembly FindAssemblyInProjectReferences(IProjectContent pc, string name) + Assembly FindAssemblyInProjectReferences(IProject pc, string name) { - foreach (IProjectContent referencedProjectContent in pc.ThreadSafeGetReferencedContents()) { - if (name == referencedProjectContent.AssemblyName) { - return this.typeResolutionService.LoadAssembly(referencedProjectContent); - } + ICompilation compilation = SD.ParserService.GetCompilation(pc); + IAssembly assembly = compilation.ReferencedAssemblies.FirstOrDefault(asm => asm.AssemblyName == name); + if (assembly != null) { + return typeResolutionService.LoadAssembly(assembly); } return null; } @@ -68,15 +72,12 @@ namespace ICSharpCode.WpfDesign.AddIn return copy; } - internal static IProjectContent GetProjectContent(OpenedFile file) + internal static IProject GetProject(OpenedFile file) { if (ProjectService.OpenSolution != null && file != null) { - IProject p = ProjectService.OpenSolution.FindProjectContainingFile(file.FileName); - if (p != null) { - return ParserService.GetProjectContent(p); - } + return ProjectService.OpenSolution.FindProjectContainingFile(file.FileName); } - return ParserService.DefaultProjectContent; + return null; } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/PropertyDescriptionService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/PropertyDescriptionService.cs index 56278ef52b..83ec0570ce 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/PropertyDescriptionService.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/PropertyDescriptionService.cs @@ -5,6 +5,7 @@ using System; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.WpfDesign.AddIn { @@ -21,7 +22,8 @@ namespace ICSharpCode.WpfDesign.AddIn public object GetDescription(DesignItemProperty property) { - IProjectContent pc = MyTypeFinder.GetProjectContent(file); + #warning reimplement this! + /*IProjectContent pc = MyTypeFinder.GetProjectContent(file); if (pc != null) { // For attached Properties if (property.DependencyFullName != null && property.Name.Contains(".")) { @@ -39,7 +41,7 @@ namespace ICSharpCode.WpfDesign.AddIn return CodeCompletionItem.ConvertDocumentation(m.Documentation); } } - } + }*/ return null; } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs index 7da0208bc1..93ac02c450 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfDisplayBinding.cs @@ -3,16 +3,17 @@ using System; using System.IO; +using ICSharpCode.Core; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Gui; using System.Xml; +using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.WpfDesign.AddIn { public class WpfPrimaryDisplayBinding : IDisplayBinding { - public bool CanCreateContentForFile(string fileName) + public bool CanCreateContentForFile(FileName fileName) { return Path.GetExtension(fileName).Equals(".xaml", StringComparison.OrdinalIgnoreCase); } @@ -22,12 +23,12 @@ namespace ICSharpCode.WpfDesign.AddIn return new WpfViewContent(file); } - public bool IsPreferredBindingForFile(string fileName) + public bool IsPreferredBindingForFile(FileName fileName) { throw new NotImplementedException(); } - public double AutoDetectFileContent(string fileName, Stream fileContent, string detectedMimeType) + public double AutoDetectFileContent(FileName fileName, Stream fileContent, string detectedMimeType) { throw new NotImplementedException(); } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs index 5aa39daf07..2b6c146d44 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; +using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Markup; @@ -18,7 +19,9 @@ using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Refactoring; +using ICSharpCode.SharpDevelop.Workbench; using ICSharpCode.WpfDesign.Designer; using ICSharpCode.WpfDesign.Designer.OutlineView; using ICSharpCode.WpfDesign.Designer.PropertyGrid; @@ -48,7 +51,7 @@ namespace ICSharpCode.WpfDesign.AddIn } DesignSurface designer; - List tasks = new List(); + List tasks = new List(); public DesignSurface DesignSurface { get { return designer; } @@ -84,7 +87,7 @@ namespace ICSharpCode.WpfDesign.AddIn delegate(XamlDesignContext context) { context.Services.AddService(typeof(IUriContext), new FileUriContext(this.PrimaryFile)); context.Services.AddService(typeof(IPropertyDescriptionService), new PropertyDescriptionService(this.PrimaryFile)); - context.Services.AddService(typeof(IEventHandlerService), new CSharpEventHandlerService(this)); + context.Services.AddService(typeof(IEventHandlerService), new SharpDevelopEventHandlerService(this)); context.Services.AddService(typeof(ITopLevelWindowService), new WpfAndWinFormsTopLevelWindowService()); context.Services.AddService(typeof(ChooseClassServiceBase), new IdeChooseClassService()); }); @@ -116,9 +119,9 @@ namespace ICSharpCode.WpfDesign.AddIn if (wasChangedInDesigner && designer.DesignContext != null) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; - settings.IndentChars = EditorControlService.GlobalOptions.IndentationString; + settings.IndentChars = SD.EditorControlService.GlobalOptions.IndentationString; settings.NewLineOnAttributes = true; - using (XmlWriter xmlWriter = XmlTextWriter.Create(stream, settings)) { + using (XmlWriter xmlWriter = XmlWriter.Create(stream, settings)) { designer.SaveDesigner(xmlWriter); } } else { @@ -134,14 +137,14 @@ namespace ICSharpCode.WpfDesign.AddIn void UpdateTasks(XamlErrorService xamlErrorService) { Debug.Assert(xamlErrorService != null); - foreach (Task task in tasks) { + foreach (SDTask task in tasks) { TaskService.Remove(task); } tasks.Clear(); foreach (XamlError error in xamlErrorService.Errors) { - var task = new Task(PrimaryFile.FileName, error.Message, error.Column - 1, error.Line - 1, TaskType.Error); + var task = new SDTask(PrimaryFile.FileName, error.Message, error.Column - 1, error.Line - 1, TaskType.Error); tasks.Add(task); TaskService.Add(task); } @@ -179,19 +182,20 @@ namespace ICSharpCode.WpfDesign.AddIn if (!propertyGridView.PropertyGrid.IsNameCorrect) return; // get the XAML file - OpenedFile fileName = this.Files.FirstOrDefault(f => f.FileName.ToString().EndsWith(".xaml")); + OpenedFile fileName = this.Files.FirstOrDefault(f => f.FileName.ToString().EndsWith(".xaml", StringComparison.OrdinalIgnoreCase)); if (fileName == null) return; // parse the XAML file - ParseInformation info = ParserService.ParseFile(fileName.FileName.ToString()); - if (info == null || info.CompilationUnit == null) return; - if (info.CompilationUnit.Classes.Count != 1) return; + ParseInformation info = SD.ParserService.Parse(fileName.FileName); + if (info == null) return; // rename the member + #warning reimplement rename! + /* IMember member = info.CompilationUnit.Classes [0].AllMembers.FirstOrDefault(m => m.Name == propertyGridView.PropertyGrid.OldName); if (member != null) { FindReferencesAndRenameHelper.RenameMember(member, propertyGridView.PropertyGrid.Name); - } + }*/ } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.AddIn.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.AddIn.csproj index ecaabadaa3..9cf625b978 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.AddIn.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.AddIn.csproj @@ -12,7 +12,7 @@ False 4 false - v4.0 + v4.5 @@ -68,7 +68,6 @@ - @@ -98,6 +97,11 @@ + + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} + ICSharpCode.NRefactory + False + {2748AD25-9C63-4E12-877B-4DCE96FBED54} ICSharpCode.SharpDevelop @@ -118,21 +122,11 @@ ICSharpCode.Core.WinForms False - - {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} - ICSharpCode.SharpDevelop.Dom - False - {8035765F-D51F-4A0C-A746-2FD100E19419} ICSharpCode.SharpDevelop.Widgets False - - {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} - FormsDesigner - False - {78CC29AC-CC79-4355-B1F2-97936DF198AC} WpfDesign.Designer diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.addin b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.addin index 84bef95e78..4d29c57412 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.addin +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/WpfDesign.addin @@ -1,7 +1,6 @@  - diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index 8febb2aff2..2eba6896b0 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -14,14 +14,15 @@ ..\..\..\..\..\..\AddIns\DisplayBindings\WpfDesign\ ..\..\..\..\..\..\AddIns\DisplayBindings\WpfDesign\ICSharpCode.WpfDesign.Designer.xml 1591 - v4.0 + v4.5 True ..\..\..\..\..\Main\ICSharpCode.SharpDevelop.snk False File False -Microsoft.Performance#CA1800;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1822 - Client + + true diff --git a/src/Main/Base/Project/Designer/IDesignerTypeResolutionService.cs b/src/Main/Base/Project/Designer/IDesignerTypeResolutionService.cs new file mode 100644 index 0000000000..9329e05e0d --- /dev/null +++ b/src/Main/Base/Project/Designer/IDesignerTypeResolutionService.cs @@ -0,0 +1,18 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.ComponentModel.Design; +using System.Reflection; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.SharpDevelop.Designer +{ + /// + /// Description of IDesignerTypeResolutionService. + /// + public interface IDesignerTypeResolutionService : ITypeResolutionService + { + Assembly LoadAssembly(IProject pc); + } +} diff --git a/src/Main/Base/Project/Designer/TypeResolutionService.cs b/src/Main/Base/Project/Designer/TypeResolutionService.cs new file mode 100644 index 0000000000..5b549e3a64 --- /dev/null +++ b/src/Main/Base/Project/Designer/TypeResolutionService.cs @@ -0,0 +1,576 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Windows.Documents; +using ICSharpCode.Core; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Gui.XmlForms; +using ICSharpCode.SharpDevelop.Project; +using Microsoft.Win32; + +namespace ICSharpCode.SharpDevelop.Designer +{ + public class TypeResolutionService : IDesignerTypeResolutionService + { + readonly static List designerAssemblies = new List(); + // hash of file content -> Assembly + readonly static Dictionary assemblyDict = new Dictionary(); + + /// + /// List of assemblies used by the form designer. This static list is not an optimal solution, + /// but better than using AppDomain.CurrentDomain.GetAssemblies(). See SD2-630. + /// + public static List DesignerAssemblies { + get { + return designerAssemblies; + } + } + + static TypeResolutionService() + { + ClearMixedAssembliesTemporaryFiles(); + DesignerAssemblies.Add(typeof(object).Assembly); + DesignerAssemblies.Add(typeof(Uri).Assembly); + DesignerAssemblies.Add(typeof(System.Drawing.Point).Assembly); + DesignerAssemblies.Add(typeof(System.Windows.Forms.Design.AnchorEditor).Assembly); + RegisterVSDesignerWorkaround(); + AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolveEventHandler; + + } + + [System.Runtime.InteropServices.DllImport("kernel32.dll")] + private static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, int dwFlags); + const int MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004; + + static void MarkFileToDeleteOnReboot(string fileName) + { + MoveFileEx(fileName, null, MOVEFILE_DELAY_UNTIL_REBOOT); + } + + static void ClearMixedAssembliesTemporaryFiles() + { + string[] files = Directory.GetFiles(Path.GetTempPath(), "*.sd_forms_designer_mixed_assembly.dll"); + foreach (string fileName in files) { + try { + File.Delete(fileName); + } catch {} + } + /* We don't need to debug controls inside the forms designer + files = Directory.GetFiles(Path.GetTempPath(), "*.pdb"); + foreach (string fileName in files) { + try { + File.Delete(fileName); + } catch {} + }*/ + } + + + string formSourceFileName; + IProject callingProject; + /// + /// Dictionary of file name -> hash of loaded assemblies for the currently designed document. + /// Used to detect changes in references assemblies. + /// + readonly Dictionary loadedAssembliesForCurrentDocument = new Dictionary(StringComparer.Ordinal); + + /// + /// Gets the project content of the project that created this TypeResolutionService. + /// Returns null when no calling project was specified. + /// + public IProject CallingProject { + get { + if (formSourceFileName != null) { + if (ProjectService.OpenSolution != null) { + return ProjectService.OpenSolution.FindProjectContainingFile(formSourceFileName); + } + formSourceFileName = null; + } + return callingProject; + } + } + + public TypeResolutionService() + { + } + + public TypeResolutionService(string formSourceFileName) + { + this.formSourceFileName = formSourceFileName; + } + + readonly HashSet projectContentsCurrentlyLoadingAssembly = new HashSet(); + + /// + /// Loads the assembly represented by the project content. Returns null on failure. + /// + public Assembly LoadAssembly(IProject pc) + { + SD.MainThread.VerifyAccess(); + // prevent StackOverflow when project contents have cyclic dependencies + // Very popular example of cyclic dependency: System <-> System.Xml + if (!projectContentsCurrentlyLoadingAssembly.Add(pc)) + return null; + + Assembly sdAssembly; + if (IsSharpDevelopAssembly(pc.ProjectContent, out sdAssembly)) + return sdAssembly; + + ICompilation compilation = SD.ParserService.GetCompilation(pc); + + try { + // load dependencies of current assembly + foreach (IAssembly asm in compilation.ReferencedAssemblies) { + LoadAssembly(asm); + } + } finally { + projectContentsCurrentlyLoadingAssembly.Remove(pc); + } + + return LoadAssembly(pc.OutputAssemblyFullPath); + } + + public Assembly LoadAssembly(IAssembly asm) + { + var project = asm.GetProject(); + if (project != null) + return LoadAssembly(project); + if (asm.IsGacAssembly()) + return LoadAssembly(new AssemblyName(asm.FullAssemblyName), false); + return LoadAssembly(asm.GetRuntimeAssemblyLocation()); + } + + readonly string sharpDevelopRoot = Directory.GetParent(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)).FullName; + + bool IsSharpDevelopAssembly(IUnresolvedAssembly pc, out Assembly assembly) + { + assembly = null; + foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { + if (!asm.IsDynamic && asm.Location.StartsWith(sharpDevelopRoot, StringComparison.OrdinalIgnoreCase) && pc.AssemblyName == asm.GetName().Name) { + assembly = asm; + return true; + } + } + return false; + } + + static string GetHash(string fileName) + { + return Path.GetFileName(fileName).ToLowerInvariant() + File.GetLastWriteTimeUtc(fileName).Ticks.ToString(); + } + + static string GetOriginalAssemblyFullPath(Assembly asm) + { + if (asm == null) throw new ArgumentNullException("asm"); + try { + return new Uri(asm.CodeBase, UriKind.Absolute).LocalPath; + } catch (UriFormatException ex) { + LoggingService.Warn("Could not determine path for assembly '" + asm.ToString() + "', CodeBase='" + asm.CodeBase + "': " + ex.Message); + return asm.Location; + } catch (InvalidOperationException ex) { + LoggingService.Warn("Could not determine path for assembly '" + asm.ToString() + "', CodeBase='" + asm.CodeBase + "': " + ex.Message); + return asm.Location; + } + } + + /// + /// Loads the file in none-locking mode. Returns null on failure. + /// + public Assembly LoadAssembly(string fileName) + { + if (!File.Exists(fileName)) + return null; + + // FIX for SD2-716, remove when designer gets its own AppDomain + foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { + try { + if (string.Equals(GetOriginalAssemblyFullPath(asm), fileName, StringComparison.OrdinalIgnoreCase)) { + RegisterAssembly(asm); + return asm; + } + } catch (NotSupportedException) { + // Fixes forum-12823 + } + } + + string hash = GetHash(fileName); + lock (assemblyDict) { + Assembly asm; + if (assemblyDict.TryGetValue(hash, out asm)) + return asm; + LoggingService.Debug("Loading assembly " + fileName + " (hash " + hash + ")"); + try { + asm = Assembly.Load(File.ReadAllBytes(fileName)); + } catch (BadImageFormatException e) { + if (e.Message.Contains("HRESULT: 0x8013141D")) { + LoggingService.Debug("Get HRESULt 0x8013141D, loading netmodule"); + //netmodule + string tempPath = Path.GetTempFileName(); + File.Delete(tempPath); + tempPath += ".sd_forms_designer_netmodule_assembly.dll"; + + try { + //convert netmodule to assembly + Process p = new Process(); + p.StartInfo.UseShellExecute = false; + p.StartInfo.FileName = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName) + Path.DirectorySeparatorChar + "al.exe"; + p.StartInfo.Arguments = "\"" + fileName +"\" /out:\"" + tempPath + "\""; + p.StartInfo.CreateNoWindow = true; + p.Start(); + p.WaitForExit(); + + if(p.ExitCode == 0 && File.Exists(tempPath)) { + byte[] asm_data = File.ReadAllBytes(tempPath); + asm = Assembly.Load(asm_data); + asm.LoadModule(Path.GetFileName(fileName), File.ReadAllBytes(fileName)); + } + } catch (Exception ex) { + MessageService.ShowException(ex, "Error calling linker for netmodule"); + } + try { + File.Delete(tempPath); + } catch {} + } else { + // Show other load errors in the compiler message view, + // but do not prevent the designer from loading. + // The error might be caused by an assembly that is + // not even needed for the designer to load. + LoggingService.Error("Error loading assembly " + fileName, e); + WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront(); + TaskService.BuildMessageViewCategory.AppendText( + StringParser.Parse("${res:FileUtilityService.ErrorWhileLoading}") + + "\r\n" + fileName + "\r\n" + e.Message + "\r\n" + ); + return null; + } + } catch (FileLoadException e) { + if (e.Message.Contains("HRESULT: 0x80131402")) { + LoggingService.Debug("Get HRESULt 0x80131402, loading mixed modes asm from disk"); + //this is C++/CLI Mixed assembly which can only be loaded from disk, not in-memory + string tempPath = Path.GetTempFileName(); + File.Delete(tempPath); + tempPath += ".sd_forms_designer_mixed_assembly.dll"; + File.Copy(fileName, tempPath); + + /* We don't need to debug controls inside the forms designer + string pdbpath = Path.GetDirectoryName(fileName) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(fileName) + ".pdb"; + if (File.Exists(pdbpath)) { + string newpdbpath = Path.GetTempPath() + Path.DirectorySeparatorChar + Path.GetFileName(pdbpath); + try { + File.Copy(pdbpath, newpdbpath); + MarkFileToDeleteOnReboot(newpdbpath); + } catch { + } + } + */ + asm = Assembly.LoadFile(tempPath); + MarkFileToDeleteOnReboot(tempPath); + } else if (e.Message.Contains("HRESULT: 0x80131019")) { + LoggingService.Debug(e.Message); + LoggingService.Debug("Attempting to load unverifiable assembly. Ignoring."); + return null; + } else { + throw; // don't ignore other load errors + } + } + + lock (designerAssemblies) { + if (!designerAssemblies.Contains(asm)) + designerAssemblies.Insert(0, asm); + } + lock (this.loadedAssembliesForCurrentDocument) { + this.loadedAssembliesForCurrentDocument[fileName] = hash; + } + assemblyDict[hash] = asm; + return asm; + } + } + + void RegisterAssembly(Assembly asm) + { + string file = GetOriginalAssemblyFullPath(asm); + if (!String.IsNullOrEmpty(file)) { + string hash = GetHash(file); + lock (assemblyDict) { + assemblyDict[hash] = asm; + } + lock (this.loadedAssembliesForCurrentDocument) { + this.loadedAssembliesForCurrentDocument[file] = hash; + } + } + lock (designerAssemblies) { + if (!designerAssemblies.Contains(asm)) + designerAssemblies.Insert(0, asm); + } + } + + public Assembly GetAssembly(AssemblyName name) + { + return LoadAssembly(name, false); + } + + public Assembly GetAssembly(AssemblyName name, bool throwOnError) + { + return LoadAssembly(name, throwOnError); + } + + Assembly LoadAssembly(AssemblyName name, bool throwOnError) + { + try { + Assembly asm = Assembly.Load(name); + RegisterAssembly(asm); + return asm; + } catch (System.IO.FileLoadException) { + if (throwOnError) + throw; + return null; + } + } + + public string GetPathOfAssembly(AssemblyName name) + { + Assembly assembly = GetAssembly(name); + if (assembly != null) { + return GetOriginalAssemblyFullPath(assembly); + } + return null; + } + + public Type GetType(string name) + { + return GetType(name, false, false); + } + + public Type GetType(string name, bool throwOnError) + { + return GetType(name, throwOnError, false); + } + + #if DEBUG + int count = 0; + #endif + + Dictionary typeCache = new Dictionary(StringComparer.Ordinal); + Dictionary typeCacheIgnoreCase = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public void ClearCaches() + { + typeCacheIgnoreCase.Clear(); + typeCache.Clear(); + } + + public Type GetType(string name, bool throwOnError, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) { + return null; + } + if (IgnoreType(name)) { + return null; + } + if (ignoreCase) { + Type cachedType; + if (typeCacheIgnoreCase.TryGetValue(name, out cachedType)) + return cachedType; + } else { + Type cachedType; + if (typeCache.TryGetValue(name, out cachedType)) + return cachedType; + } + #if DEBUG + if (!name.StartsWith("System.", StringComparison.Ordinal)) { + count++; + LoggingService.Debug(count + " TypeResolutionService: Looking for " + name); + } + #endif + try { + + Type type = Type.GetType(name, false, ignoreCase); + + if (type == null) { + IProject p = CallingProject; + if (p != null) { + ICompilation compilation = SD.ParserService.GetCompilation(p); + ITypeDefinition definition = ReflectionHelper.ParseReflectionName(name) + .Resolve(compilation).GetDefinition(); + if (definition != null) { + Assembly assembly = LoadAssembly(definition.ParentAssembly); + if (assembly != null) { + type = assembly.GetType(name, false, ignoreCase); + } + } + } + } + + // type lookup for typename, assembly, xyz style lookups + if (type == null) { + int idx = name.IndexOf(",", StringComparison.Ordinal); + if (idx > 0) { + string[] splitName = name.Split(','); + string typeName = splitName[0]; + string assemblyName = splitName[1].Substring(1); + Assembly assembly = null; + try { + assembly = Assembly.Load(assemblyName); + } catch (Exception e) { + LoggingService.Error(e); + } + if (assembly != null) { + string fileName = GetOriginalAssemblyFullPath(assembly); + if (!String.IsNullOrEmpty(fileName)) { + lock (loadedAssembliesForCurrentDocument) { + loadedAssembliesForCurrentDocument [fileName] = GetHash(fileName); + } + } + lock (designerAssemblies) { + if (!designerAssemblies.Contains(assembly)) + designerAssemblies.Add(assembly); + } + type = assembly.GetType(typeName, false, ignoreCase); + } else { + type = Type.GetType(typeName, false, ignoreCase); + } + } + } + + if (type == null) { + lock (designerAssemblies) { + foreach (Assembly asm in DesignerAssemblies) { + try { + Type t = asm.GetType(name, false); + if (t != null) { + AddToCache(name, t, ignoreCase); + return t; + } + } catch (FileNotFoundException) { + } catch (FileLoadException) { + } catch (BadImageFormatException) { + // ignore assembly load errors + } + } + } + } + + if (throwOnError && type == null) + throw new TypeLoadException(name + " not found by TypeResolutionService"); + AddToCache(name, type, ignoreCase); + return type; + } catch (Exception e) { + LoggingService.Error(e); + } + return null; + } + + void AddToCache(string name, Type type, bool ignoreCase) + { + if (type == null) + return; + if (ignoreCase) { + typeCacheIgnoreCase.Add(name, type); + } else { + typeCache.Add(name, type); + } + } + + public void ReferenceAssembly(AssemblyName name) + { + ICSharpCode.Core.LoggingService.Warn("TODO: Add Assembly reference : " + name); + } + + /// + /// Gets whether an assembly referenced by the currently designed document + /// has been changed since it has been loaded. + /// + public bool ReferencedAssemblyChanged { + get { + return this.loadedAssembliesForCurrentDocument.Any( + pair => !File.Exists(pair.Key) || !String.Equals(pair.Value, GetHash(pair.Key), StringComparison.Ordinal) + ); + } + } + + #region VSDesigner workarounds + /// + /// HACK - Ignore any requests for types from the Microsoft.VSDesigner + /// assembly. There are smart tag problems if data adapter + /// designers are used from this assembly. + /// + bool IgnoreType(string name) + { + int idx = name.IndexOf(","); + if (idx > 0) { + string[] splitName = name.Split(','); + string assemblyName = splitName[1].Substring(1); + if (assemblyName == "Microsoft.VSDesigner") { + return true; + } + } + return false; + } + + static string vsDesignerIdeDir; + + static void RegisterVSDesignerWorkaround() + { + if (vsDesignerIdeDir == null) { + vsDesignerIdeDir = ""; + try { + using(RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS")) { + if (key != null) { + vsDesignerIdeDir = key.GetValue("VS7CommonDir") as string ?? ""; + } + } + } catch (System.Security.SecurityException) { + // registry access might be denied + } + if (vsDesignerIdeDir.Length > 0) { + vsDesignerIdeDir = Path.Combine(vsDesignerIdeDir, "IDE"); + AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args) { + string shortName = args.Name; + if (shortName.IndexOf(',') >= 0) { + shortName = shortName.Substring(0, shortName.IndexOf(',')); + } + if (shortName.StartsWith("Microsoft.") + && File.Exists(Path.Combine(vsDesignerIdeDir, shortName + ".dll"))) + { + return Assembly.LoadFrom(Path.Combine(vsDesignerIdeDir, shortName + ".dll")); + } + return null; + }; + } + } + } + #endregion + + static Assembly AssemblyResolveEventHandler(object sender, ResolveEventArgs args) + { + LoggingService.Debug("TypeResolutionService: AssemblyResolveEventHandler: " + args.Name); + + Assembly lastAssembly = null; + + foreach (Assembly asm in TypeResolutionService.DesignerAssemblies) { + if (asm.FullName == args.Name) { + return asm; + } + } + + foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { + if (asm.FullName == args.Name) { + lastAssembly = asm; + } + } + if (lastAssembly != null) { + TypeResolutionService.DesignerAssemblies.Add(lastAssembly); + LoggingService.Info("ICSharpAssemblyResolver found..." + args.Name); + } + return lastAssembly; + } + } +} diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 6dcd191021..6142e3c9c4 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -95,6 +95,8 @@ Src\Project\MSBuildEngine\ExtendedBinaryReader.cs + + @@ -163,6 +165,7 @@ + @@ -504,10 +507,10 @@ - - - - + + + + @@ -829,6 +832,7 @@ + @@ -891,7 +895,7 @@ - + diff --git a/src/Main/Base/Project/Src/Refactoring/ContextAction.cs b/src/Main/Base/Project/Refactoring/ContextAction.cs similarity index 100% rename from src/Main/Base/Project/Src/Refactoring/ContextAction.cs rename to src/Main/Base/Project/Refactoring/ContextAction.cs diff --git a/src/Main/Base/Project/Src/Refactoring/EditorRefactoringContext.cs b/src/Main/Base/Project/Refactoring/EditorRefactoringContext.cs similarity index 100% rename from src/Main/Base/Project/Src/Refactoring/EditorRefactoringContext.cs rename to src/Main/Base/Project/Refactoring/EditorRefactoringContext.cs diff --git a/src/Main/Base/Project/Refactoring/ICodeGenerator.cs b/src/Main/Base/Project/Refactoring/ICodeGenerator.cs new file mode 100644 index 0000000000..052da7a65d --- /dev/null +++ b/src/Main/Base/Project/Refactoring/ICodeGenerator.cs @@ -0,0 +1,18 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.TypeSystem; + +namespace ICSharpCode.SharpDevelop.Refactoring +{ + /// + /// Description of ICodeGenerator. + /// + public interface ICodeGenerator + { + void AddAttribute(IEntity target, IAttribute attribute); + void InsertEventHandler(ITypeDefinition target, string name, IEvent eventDefinition, bool jumpTo); + } +} diff --git a/src/Main/Base/Project/Src/Refactoring/IContextAction.cs b/src/Main/Base/Project/Refactoring/IContextAction.cs similarity index 100% rename from src/Main/Base/Project/Src/Refactoring/IContextAction.cs rename to src/Main/Base/Project/Refactoring/IContextAction.cs diff --git a/src/Main/Base/Project/Src/Refactoring/IContextActionProvider.cs b/src/Main/Base/Project/Refactoring/IContextActionProvider.cs similarity index 100% rename from src/Main/Base/Project/Src/Refactoring/IContextActionProvider.cs rename to src/Main/Base/Project/Refactoring/IContextActionProvider.cs diff --git a/src/Main/Base/Project/Src/Gui/Components/FontSelector.xaml.cs b/src/Main/Base/Project/Src/Gui/Components/FontSelector.xaml.cs index 8c3b016308..0c0e022e43 100644 --- a/src/Main/Base/Project/Src/Gui/Components/FontSelector.xaml.cs +++ b/src/Main/Base/Project/Src/Gui/Components/FontSelector.xaml.cs @@ -152,7 +152,7 @@ namespace ICSharpCode.SharpDevelop.Gui [ValueConversion(typeof(int), typeof(double))] public class SDFontSizeConverter : IValueConverter { - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) throw new ArgumentNullException("value"); @@ -161,7 +161,7 @@ namespace ICSharpCode.SharpDevelop.Gui throw new NotSupportedException("Cannot convert value of type " + value.GetType()); } - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) throw new ArgumentNullException("value"); diff --git a/src/Main/Base/Project/Src/Project/AbstractProject.cs b/src/Main/Base/Project/Src/Project/AbstractProject.cs index cc69c042cb..d21c0b5e0c 100644 --- a/src/Main/Base/Project/Src/Project/AbstractProject.cs +++ b/src/Main/Base/Project/Src/Project/AbstractProject.cs @@ -19,6 +19,7 @@ using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui.OptionPanels; using ICSharpCode.SharpDevelop.Parser; +using ICSharpCode.SharpDevelop.Refactoring; using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.SharpDevelop.Project @@ -315,6 +316,13 @@ namespace ICSharpCode.SharpDevelop.Project } } + [Browsable(false)] + public virtual ICodeGenerator CodeGenerator { + get { + throw new NotSupportedException("This project does not support code generation!"); + } + } + /// /// Gets the full path of the output assembly. /// Returns null when the project does not output any assembly. diff --git a/src/Main/Base/Project/Src/Project/IProject.cs b/src/Main/Base/Project/Src/Project/IProject.cs index d4e748a79e..03ba849777 100644 --- a/src/Main/Base/Project/Src/Project/IProject.cs +++ b/src/Main/Base/Project/Src/Project/IProject.cs @@ -2,7 +2,6 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.CodeDom.Compiler; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; @@ -16,6 +15,7 @@ using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Parser; +using ICSharpCode.SharpDevelop.Refactoring; namespace ICSharpCode.SharpDevelop.Project { @@ -304,6 +304,11 @@ namespace ICSharpCode.SharpDevelop.Project /// IAmbience GetAmbience(); + /// + /// Returns the ICodeGenerator implementation for this project. + /// + ICodeGenerator CodeGenerator { get; } + /// /// Prepares searching for references to the specified entity. /// This method should calculate the amount of work to be done (e.g. using the number of files to search through), diff --git a/src/Main/Base/Project/Util/SharpDevelopExtensions.cs b/src/Main/Base/Project/Util/SharpDevelopExtensions.cs index 008c048dac..bc2b9a61d6 100644 --- a/src/Main/Base/Project/Util/SharpDevelopExtensions.cs +++ b/src/Main/Base/Project/Util/SharpDevelopExtensions.cs @@ -380,6 +380,14 @@ namespace ICSharpCode.SharpDevelop return FileName.Create(assembly.UnresolvedAssembly.Location); } + public static bool IsGacAssembly(this IAssembly assembly) + { + if (assembly == null) + throw new ArgumentNullException("assembly"); + return !(assembly.UnresolvedAssembly is IProjectContent) + && SD.GlobalAssemblyCache.FindAssemblyInNetGac(new DomAssemblyName(assembly.FullAssemblyName)) != null; + } + /// /// Gets the ambience for the specified compilation. /// Never returns null. @@ -605,6 +613,19 @@ namespace ICSharpCode.SharpDevelop return s.Substring(0, length) + "..."; } + /// + /// Removes any character given in the array from the given string. + /// + public static string RemoveAny(this string s, params char[] chars) + { + if (string.IsNullOrEmpty(s)) + return s; + var b = new StringBuilder(s); + foreach (char ch in chars) { + b.Replace(ch.ToString(), ""); + } + return b.ToString(); + } public static string Replace(this string original, string pattern, string replacement, StringComparison comparisonType) {