diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Gui/ViewContentControl.cs b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Gui/ViewContentControl.cs index 4f17d0cfbb..00da873a51 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Gui/ViewContentControl.cs +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Gui/ViewContentControl.cs @@ -17,6 +17,7 @@ using System.IO; using System.Drawing.Design; using ICSharpCode.Core; +using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.TextEditor; using ICSharpCode.TextEditor.Document; @@ -154,15 +155,8 @@ namespace WorkflowDesigner selectionService.SelectionChanged += new EventHandler(SelectionChangedHandler); } - void UpdateCodeCompileUniteCompileUnit() - { - IWorkflowDesignerEventBindingService srv = this.DesignerHost.GetService(typeof(IEventBindingService)) as IWorkflowDesignerEventBindingService; - srv.UpdateCodeCompileUnit(); - } - void ComponentAddedHandler(object sender, ComponentEventArgs args) { - UpdateCodeCompileUniteCompileUnit(); viewContent.PrimaryFile.MakeDirty(); LoggingService.Debug("ComponentAddedHandler"); } @@ -174,7 +168,6 @@ namespace WorkflowDesigner void ComponentChangedHandler(object sender, ComponentChangedEventArgs args) { - UpdateCodeCompileUniteCompileUnit(); viewContent.PrimaryFile.MakeDirty(); ISelectionService selectionService = (ISelectionService)designSurface.GetService(typeof(ISelectionService)); UpdatePropertyPadSelection(selectionService); diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/NRefactoryDesignerLoader.cs b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/NRefactoryDesignerLoader.cs index 00c0b62832..be78855d3a 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/NRefactoryDesignerLoader.cs +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/NRefactoryDesignerLoader.cs @@ -100,7 +100,7 @@ namespace WorkflowDesigner LoaderHost.AddService(typeof(IToolboxService), new WorkflowToolboxService(LoaderHost)); LoaderHost.AddService(typeof(MemberRelationshipService), new DefaultMemberRelationshipService()); LoaderHost.AddService(typeof(IMenuCommandService), new WorkflowMenuCommandService(LoaderHost)); - LoaderHost.AddService(typeof(ITypeResolutionService), new TypeResolutionService(LoaderHost)); + LoaderHost.AddService(typeof(ITypeResolutionService), new TypeResolutionService(ProjectService.OpenSolution.FindProjectContainingFile(this.textEditorControl.FileName),LoaderHost)); LoaderHost.AddService(typeof(IPropertyValueUIService), new PropertyValueUIService()); base.Initialize(); diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/XomlDesignerLoader.cs b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/XomlDesignerLoader.cs index 2ed26ca20c..79ab132c20 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/XomlDesignerLoader.cs +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Loaders/XomlDesignerLoader.cs @@ -130,7 +130,7 @@ namespace WorkflowDesigner LoaderHost.AddService(typeof(IToolboxService), new WorkflowToolboxService(LoaderHost)); LoaderHost.AddService(typeof(ITypeProvider), TypeProviderService.GetTypeProvider(Project)); LoaderHost.AddService(typeof(IMenuCommandService), new WorkflowMenuCommandService(LoaderHost)); - LoaderHost.AddService(typeof(ITypeResolutionService), new TypeResolutionService(LoaderHost)); + LoaderHost.AddService(typeof(ITypeResolutionService), new TypeResolutionService(ProjectService.OpenSolution.FindProjectContainingFile(this.FileName),LoaderHost)); LoaderHost.AddService(typeof(IPropertyValueUIService), new PropertyValueUIService()); base.Initialize(); @@ -167,7 +167,7 @@ namespace WorkflowDesigner if (compositeActivity != null) AddChildren(compositeActivity); - SetBaseComponentClassName(rootActivity.GetType().FullName); + SetBaseComponentClassName(rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty) as string); // Load the rules if (File.Exists(rulesFileName)) { diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/EventBindingService/WorkflowDesignerEventBindingService.cs b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/EventBindingService/WorkflowDesignerEventBindingService.cs index c78451a0fd..83a7ab157a 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/EventBindingService/WorkflowDesignerEventBindingService.cs +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/EventBindingService/WorkflowDesignerEventBindingService.cs @@ -30,6 +30,7 @@ using ICSharpCode.TextEditor.Document; using ICSharpCode.NRefactory.Visitors; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Ast; +using ICSharpCode.SharpDevelop.Project; #endregion @@ -41,7 +42,6 @@ namespace WorkflowDesigner public abstract class WorkflowDesignerEventBindingService : IWorkflowDesignerEventBindingService, IServiceProvider { string codeFileName; - CodeCompileUnit ccu; protected WorkflowDesignerEventBindingService(IServiceProvider provider, string codeSeparationFileName) { @@ -55,15 +55,11 @@ namespace WorkflowDesigner { LoggingService.Debug("UpdateCCU"); - TypeProvider typeProvider = (TypeProvider)this.GetService(typeof(ITypeProvider)); - - if (ccu != null) - typeProvider.RemoveCodeCompileUnit(ccu); - - ccu = Parse(); + IProject project = ProjectService.OpenSolution.FindProjectContainingFile(codeFileName); + FileProjectItem fpi = project.FindFile(codeFileName); - if (ccu != null) - typeProvider.AddCodeCompileUnit(ccu); + TypeProviderService.UpdateCodeCompileUnit(fpi); + } public string CodeFileName { diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeProviderService.cs b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeProviderService.cs index 1279488781..65f15e85ee 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeProviderService.cs +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeProviderService.cs @@ -7,15 +7,22 @@ #region Using using System; +using System.Collections.Specialized; using System.IO; using System.Collections; using System.Collections.Generic; using System.Workflow.ComponentModel.Compiler; using System.Reflection; +using System.CodeDom; +using System.CodeDom.Compiler; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop; +using ICSharpCode.Core; +using ICSharpCode.NRefactory.Visitors; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.NRefactory; #endregion namespace WorkflowDesigner @@ -29,8 +36,9 @@ namespace WorkflowDesigner public class TypeProviderService { private static Dictionary providers = null; + private static Dictionary codeCompileUnits = null; - #region Property Accessorors + #region Property Accessors private static Dictionary Providers { get { if (providers == null) @@ -39,6 +47,15 @@ namespace WorkflowDesigner return providers; } } + private static Dictionary CodeCompileUnits { + get { + if (codeCompileUnits == null) + codeCompileUnits = new Dictionary(); + + return codeCompileUnits; + } + } + #endregion @@ -64,14 +81,19 @@ namespace WorkflowDesigner TypeProvider typeProvider = new TypeProvider(null); - // Always need the core runtime! - Assembly assembly2 = AppDomain.CurrentDomain.Load("mscorlib"); - typeProvider.AddAssembly(assembly2); + // Add the essential designer assemblies. + typeProvider.AddAssembly(typeof(System.Object).Assembly); + typeProvider.AddAssembly(typeof(System.ComponentModel.Design.Serialization.CodeDomSerializer).Assembly); + typeProvider.AddAssembly(typeof(System.Workflow.ComponentModel.DependencyObject).Assembly); + typeProvider.AddAssembly(typeof(System.Workflow.Activities.CodeActivity).Assembly); + typeProvider.AddAssembly(typeof(System.Workflow.Runtime.WorkflowRuntime).Assembly); + // Just return the basic provider if not related to a project. if (project == null) return typeProvider; LoadProjectReferences(project, typeProvider); + RefreshCodeCompileUnits(project, typeProvider); Providers.Add(project, typeProvider); @@ -88,8 +110,10 @@ namespace WorkflowDesigner Assembly assembly = LoadAssembly(item, AppDomain.CurrentDomain); - if (assembly != null) - typeProvider.AddAssembly(assembly); + if (assembly != null) { + if (!typeProvider.ReferencedAssemblies.Contains(assembly)) + typeProvider.AddAssembly(assembly); + } } } @@ -187,5 +211,133 @@ namespace WorkflowDesigner } + private static void RefreshCodeCompileUnits(IProject project, TypeProvider typeProvider) + { + ICSharpCode.Core.LoggingService.Debug("RefreshCodeCompileUnits"); + + // First use the workflow compiler to create one ccu for all the workflows + StringCollection files = new StringCollection(); + foreach (ProjectItem item in project.GetItemsOfType(ItemType.Content)){ + files.AddRange(GetRelatedFiles(project, item.FileName)); + } + + string[] s = new string[files.Count]; + for (int i = 0; i < files.Count; i++) + s[i] = files[i]; + + CodeCompileUnit ccu = ParseXoml(project, s); + if (ccu != null) { + typeProvider.AddCodeCompileUnit(ccu); + cp.UserCodeCompileUnits.Add(ccu); + } + + // Now create one ccu for each source file. + foreach (ProjectItem item in project.GetItemsOfType(ItemType.Compile)){ + ICSharpCode.Core.LoggingService.Debug(item.FileName); + if (item is FileProjectItem) { + ccu = Parse(item.FileName); + if (ccu != null) { + typeProvider.AddCodeCompileUnit(ccu); + cp.UserCodeCompileUnits.Add(ccu); + CodeCompileUnits.Add(item as FileProjectItem, ccu); + } + } + } + } + + public static void UpdateCodeCompileUnit(FileProjectItem item) + { + TypeProvider typeProvider = Providers[item.Project]; + if (typeProvider == null) + return; + + // Remove the old ccu + if (CodeCompileUnits.ContainsKey(item)) + typeProvider.RemoveCodeCompileUnit(CodeCompileUnits[item]); + + // Build the new unit. + CodeCompileUnit codeCompileUnit = Parse(item.FileName); + + // Now add the new unit. + if ( codeCompileUnit != null) { + typeProvider.AddCodeCompileUnit(codeCompileUnit); + if (CodeCompileUnits.ContainsKey(item)) + CodeCompileUnits[item] = codeCompileUnit; + else + CodeCompileUnits.Add(item, codeCompileUnit); + } + + } + + static WorkflowCompilerParameters cp = new WorkflowCompilerParameters(); + + private static string[] GetRelatedFiles(IProject project, string fileName) + { + StringCollection files = new StringCollection(); + files.Add(fileName); + + foreach (ProjectItem item in project.Items){ + if (item is FileProjectItem) { + FileProjectItem fItem = item as FileProjectItem; + if ((item.ItemType == ItemType.Compile) || (item.ItemType == ItemType.Content)) { + if (fItem.DependentUpon == Path.GetFileName(fileName)){ + files.Add(item.FileName); + } + } + } + } + + + string[] s = new string[files.Count]; + for (int i = 0; i < files.Count; i++) + s[i] = files[i]; + + return s; + } + + private static CodeCompileUnit ParseXoml(IProject project, string[] fileNames) + { + ICSharpCode.Core.LoggingService.DebugFormatted("ParseXoml {0}", fileNames); + + cp.GenerateCodeCompileUnitOnly = true; + cp.LanguageToUse = "CSharp"; + + WorkflowCompiler compiler = new WorkflowCompiler(); + WorkflowCompilerResults results = compiler.Compile(cp, fileNames); + + if (results.Errors.Count > 0) { + foreach (CompilerError e in results.Errors) { + ICSharpCode.Core.LoggingService.ErrorFormatted("{0}: {1}: {2}", e.Line, e.ErrorNumber, e.ErrorText); + } + return null; + } + + return results.CompiledUnit; + + } + + private static CodeCompileUnit Parse(string fileName) + { + ICSharpCode.Core.LoggingService.DebugFormatted("Parse {0}", fileName); + + string fileContent = ParserService.GetParseableFileContent(fileName); + + ICSharpCode.NRefactory.IParser parser = ICSharpCode.NRefactory.ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(fileContent)); + parser.Parse(); + if (parser.Errors.Count > 0) { + return null; + } + + + CodeDomVisitor visitor = new CodeDomVisitor(); + try { + visitor.VisitCompilationUnit(parser.CompilationUnit, null); + return visitor.codeCompileUnit; + } catch (Exception e) { + ICSharpCode.Core.LoggingService.Error("Parse", e); + return null; + } + } + } } diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeResolutionService.cs b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeResolutionService.cs index 33339b75c5..ef597fb314 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeResolutionService.cs +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/TypeResolutionService.cs @@ -24,10 +24,13 @@ namespace WorkflowDesigner /// public class TypeResolutionService : ITypeResolutionService, IServiceProvider { + IProject project; + #region Constructors - public TypeResolutionService(IServiceProvider provider) + public TypeResolutionService(IProject project, IServiceProvider provider) { + this.project = project; this.provider = provider; } #endregion @@ -68,29 +71,32 @@ namespace WorkflowDesigner // Ignoring versions numbers on types. string[] splitName = name.Split(','); - string typeName = splitName[0]; + string typeName = splitName[0].Replace('+','.'); // Check for the type ourselves in the projects referenced assemblies // as the System.Workflow.ComponentModel.Compiler.TypeProvider does // not seem find private types in referenced assemblies! TypeProvider typeProvider = provider.GetService(typeof(ITypeProvider)) as TypeProvider; - if (typeProvider != null) - { - + if (typeProvider != null) { foreach (Assembly asm in typeProvider.ReferencedAssemblies){ - type = asm.GetType(typeName, throwOnError, ignoreCase); - if (type != null) - return type; + foreach (Module module in asm.GetModules()){ + type = module.GetType(typeName, throwOnError, ignoreCase); + if (type != null) + return type; + } } } - + if (type == null) - { + type = typeProvider.GetType(typeName, throwOnError); + + // TODO: Need to check current project see if we can find it! + + if (type == null) { LoggingService.WarnFormatted("TypeResolutionService failed to find type {0}", typeName); if (throwOnError) throw new TypeLoadException(name + " not found by TypeResolutionService"); } - return type; } @@ -107,6 +113,8 @@ namespace WorkflowDesigner return; } + LoggingService.DebugFormatted("TypeResolutionService.ReferenceAssembly {0}", name); + // TODO: Not in project so add the reference. // IProject project = ProjectService.CurrentProject; // if (project != null) { diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/WorkflowSideTabService.cs b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/WorkflowSideTabService.cs index 36004b4aeb..821a86e85a 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/WorkflowSideTabService.cs +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Src/Services/WorkflowSideTabService.cs @@ -19,6 +19,7 @@ using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Widgets.SideBar; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Dom; #endregion namespace WorkflowDesigner @@ -247,6 +248,10 @@ namespace WorkflowDesigner // Cannot use LoadSideTabFromAssembly as it will only // load public components from the assembly. + IProjectContent projectContent = ParserService.GetProjectContent(project); + foreach (IProjectContent pc in projectContent.ReferencedContents){ + //LoggingService.DebugFormatted(pc.ToString()); + } SortSideTabItems(sideTab); return sideTab; diff --git a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Templates/Files/CSharp/Activity.xft b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Templates/Files/CSharp/Activity.xft index 803d761bd7..395db2cb67 100644 --- a/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Templates/Files/CSharp/Activity.xft +++ b/src/AddIns/DisplayBindings/WorkflowDesigner/Project/Templates/Files/CSharp/Activity.xft @@ -26,7 +26,7 @@ namespace ${StandardNamespace} } }]]> - - False + False