diff --git a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/DesignerViewContent.cs b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/DesignerViewContent.cs index 9c991c2d57..b8320be659 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/DesignerViewContent.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/DesignerViewContent.cs @@ -263,6 +263,7 @@ namespace ICSharpCode.FormsDesigner LoggingService.Info("Form Designer: BEGIN INITIALIZE"); DefaultServiceContainer serviceContainer = new DefaultServiceContainer(); + serviceContainer.AddService(typeof(IMessageService), new FormsMessageService()); serviceContainer.AddService(typeof(System.Windows.Forms.Design.IUIService), new UIService()); serviceContainer.AddService(typeof(System.Drawing.Design.IToolboxService), ToolboxProvider.ToolboxService); @@ -272,12 +273,12 @@ namespace ICSharpCode.FormsDesigner serviceContainer.AddService(typeof(System.ComponentModel.Design.IResourceService), new DesignerResourceService(this.resourceStore)); AmbientProperties ambientProperties = new AmbientProperties(); serviceContainer.AddService(typeof(AmbientProperties), ambientProperties); - this.typeResolutionService = new TypeResolutionService(this.PrimaryFileName); + this.typeResolutionService = new TypeResolutionService(this.PrimaryFileName, serviceContainer, new DomTypeLocator(this.PrimaryFileName)); serviceContainer.AddService(typeof(ITypeResolutionService), this.typeResolutionService); serviceContainer.AddService(typeof(DesignerOptionService), new SharpDevelopDesignerOptionService()); serviceContainer.AddService(typeof(ITypeDiscoveryService), new TypeDiscoveryService()); serviceContainer.AddService(typeof(MemberRelationshipService), new DefaultMemberRelationshipService()); - serviceContainer.AddService(typeof(ProjectResourceService), new ProjectResourceService(ParserService.GetParseInformation(this.DesignerCodeFile.FileName).CompilationUnit.ProjectContent)); + serviceContainer.AddService(typeof(IProjectResourceService), new ProjectResourceService(ParserService.GetParseInformation(this.DesignerCodeFile.FileName).CompilationUnit.ProjectContent)); // Provide the ImageResourceEditor for all Image and Icon properties this.addedTypeDescriptionProviders.Add(typeof(Image), TypeDescriptor.AddAttributes(typeof(Image), new EditorAttribute(typeof(ImageResourceEditor), typeof(System.Drawing.Design.UITypeEditor)))); diff --git a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/FormsDesigner.AddIn.csproj b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/FormsDesigner.AddIn.csproj index c5e1b2665c..2df14c1514 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/FormsDesigner.AddIn.csproj +++ b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/FormsDesigner.AddIn.csproj @@ -79,9 +79,12 @@ + + + Form @@ -107,6 +110,11 @@ ICSharpCode.Core False + + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} + ICSharpCode.SharpDevelop.Dom + False + {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} FormsDesigner diff --git a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/DomTypeLocator.cs b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/DomTypeLocator.cs new file mode 100644 index 0000000000..dfdf135725 --- /dev/null +++ b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/DomTypeLocator.cs @@ -0,0 +1,126 @@ +// 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 ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Project; + +namespace ICSharpCode.FormsDesigner.Services +{ + public class DomTypeLocator : ITypeLocator + { + string formSourceFileName; + IProjectContent callingProject; + + public System.ComponentModel.Design.ITypeResolutionService ParentService { get; set; } + + /// + /// Gets the project content of the project that created this TypeResolutionService. + /// Returns null when no calling project was specified. + /// + public IProjectContent CallingProject { + get { + if (formSourceFileName != null) { + if (ProjectService.OpenSolution != null) { + IProject p = ProjectService.OpenSolution.FindProjectContainingFile(formSourceFileName); + if (p != null) { + callingProject = ParserService.GetProjectContent(p); + } + } + formSourceFileName = null; + } + return callingProject; + } + } + + public DomTypeLocator(string formSourceFileName) + { + this.formSourceFileName = formSourceFileName; + } + + static readonly Dictionary projectContentsCurrentlyLoadingAssembly = new Dictionary(); + + public string LocateType(string name, out string[] referencedAssemblies) + { + IProjectContent pc = CallingProject; + + if (pc != null) { + // find assembly containing type by using SharpDevelop.Dom + IClass foundClass; + if (name.Contains("`")) { + int typeParameterCount; + int.TryParse(name.Substring(name.IndexOf('`') + 1), out typeParameterCount); + foundClass = pc.GetClass(name.Substring(0, name.IndexOf('`')).Replace('+', '.'), typeParameterCount); + } else { + foundClass = pc.GetClass(name.Replace('+', '.'), 0); + } + if (foundClass != null) { + string path = GetPathToAssembly(pc); + + if (string.IsNullOrEmpty(path)) { + referencedAssemblies = new string[0]; + return ""; + } + + List assemblies = new List(); + + FindReferencedAssemblies(assemblies, pc); + + if (assemblies.Contains(path)) + assemblies.Remove(path); + + referencedAssemblies = assemblies.ToArray(); + return path; + } + } + + referencedAssemblies = new string[0]; + return ""; + } + + void FindReferencedAssemblies(List assemblies, IProjectContent pc) + { + // prevent StackOverflow when project contents have cyclic dependencies + // Very popular example of cyclic dependency: System <-> System.Xml (yes, really!) + if (projectContentsCurrentlyLoadingAssembly.ContainsKey(pc)) + return; + projectContentsCurrentlyLoadingAssembly.Add(pc, null); + + string path = GetPathToAssembly(assemblies, pc); + + if (!string.IsNullOrEmpty(path) && !assemblies.Contains(path)) + assemblies.Add(path); + + try { + // load dependencies of current assembly + foreach (IProjectContent rpc in pc.ReferencedContents) { + if (rpc is ParseProjectContent) { + FindReferencedAssemblies(assemblies, rpc); + } else if (rpc is ReflectionProjectContent) { + ReflectionProjectContent rrpc = (ReflectionProjectContent)rpc; + if (!GacInterop.IsWithinGac(rrpc.AssemblyLocation)) + FindReferencedAssemblies(assemblies, rpc); + } + } + } finally { + projectContentsCurrentlyLoadingAssembly.Remove(pc); + } + } + + string GetPathToAssembly(IProjectContent pc) + { + if (pc.Project != null) + return ((IProject)pc.Project).OutputAssemblyFullPath; + else if (pc is ReflectionProjectContent) + return ((ReflectionProjectContent)pc).AssemblyLocation; + + return null; + } + + public bool IsGacAssembly(string path) + { + return GacInterop.IsWithinGac(path); + } + } +} diff --git a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/FormsMessageService.cs b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/FormsMessageService.cs new file mode 100644 index 0000000000..8a54b75ab6 --- /dev/null +++ b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/FormsMessageService.cs @@ -0,0 +1,29 @@ +// 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.Core; + +namespace ICSharpCode.FormsDesigner.Services +{ + /// + /// Description of MessageService. + /// + public class FormsMessageService : IMessageService + { + public void ShowOutputPad() + { + WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront(); + } + + public void AppendTextToBuildMessages(string text) + { + TaskService.BuildMessageViewCategory.AppendText(StringParser.Parse(text)); + } + + public void ShowException(Exception ex, string message) + { + MessageService.ShowException(ex, message); + } + } +} diff --git a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/ProjectResourceService.cs b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/ProjectResourceService.cs index 2913246b5b..1a49e53757 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/ProjectResourceService.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/ProjectResourceService.cs @@ -16,21 +16,19 @@ namespace ICSharpCode.FormsDesigner.Services /// /// Supports project-level resources in the Windows.Forms designer. /// - public sealed class ProjectResourceService + public sealed class ProjectResourceService : IProjectResourceService { - public const string ProjectResourceKey = "SDProjectResource_"; - IProjectContent projectContent; string stringLiteralDelimiter; bool designerSupportsProjectResources = true; - + public ProjectResourceService(IProjectContent projectContent) { if (projectContent == null) throw new ArgumentNullException("projectContent"); this.projectContent = projectContent; } - + public IProjectContent ProjectContent { get { return projectContent; } set { @@ -42,12 +40,16 @@ namespace ICSharpCode.FormsDesigner.Services } } } - - public bool DesignerSupportsProjectResources { + + public bool DesignerSupportsProjectResources { get { return designerSupportsProjectResources; } set { designerSupportsProjectResources = value; } } + public string ProjectResourceKey { + get { return "SDProjectResource_"; } + } + /// /// Gets the string literal delimiter for the current language /// by generating code for a known literal. @@ -62,7 +64,7 @@ namespace ICSharpCode.FormsDesigner.Services return stringLiteralDelimiter; } } - + /// /// Gets the project resource from the specified expression. /// @@ -73,22 +75,22 @@ namespace ICSharpCode.FormsDesigner.Services LoggingService.Info("Target of possible project resources property reference is not a type reference, but " + propRef.TargetObject.ToString() + "."); return null; } - + // Get the (generated) class where the resource is defined. IClass resourceClass = this.projectContent.GetClassByReflectionName(typeRef.Type.BaseType, true); if (resourceClass == null) { throw new InvalidOperationException("Could not find class for project resources: '" + typeRef.Type.BaseType + "'."); } - + if (resourceClass.CompilationUnit == null || resourceClass.CompilationUnit.FileName == null) { return null; } - + // Make sure the class we have found is a generated resource class. if (!IsGeneratedResourceClass(resourceClass)) { return null; } - + // Get the name of the resource file based on the file that contains the generated class. string resourceFileName = Path.GetFileNameWithoutExtension(resourceClass.CompilationUnit.FileName); if (resourceFileName.EndsWith("Designer", StringComparison.OrdinalIgnoreCase)) { @@ -102,59 +104,59 @@ namespace ICSharpCode.FormsDesigner.Services } else { throw new FileNotFoundException("Could not find the resource file for type '" + resourceClass.FullyQualifiedName + "'. Tried these file names: '" + resourceFileName + ".(resources|resx)'."); } - + // Get the property for the resource. IProperty prop = resourceClass.Properties.SingleOrDefault(p => p.Name == propRef.PropertyName); if (prop == null) { throw new InvalidOperationException("Property '" + propRef.PropertyName + "' not found in type '" + resourceClass.FullyQualifiedName + "'."); } - + if (!prop.CanGet) { throw new InvalidOperationException("Property '" + propRef.PropertyName + "' in type '" + resourceClass.FullyQualifiedName + "' does not have a getter."); } - + // Get the code of the resource class and // extract the resource key from the property. // This is necessary because the key may differ from the property name // if special characters are used. // It would be better if we could use a real code parser for this, but // that is not possible without getting dependent on the programming language. - + IDocument doc = new ICSharpCode.SharpDevelop.Editor.AvalonEdit.AvalonEditDocumentAdapter(); doc.Text = ParserService.GetParseableFileContent(resourceClass.CompilationUnit.FileName).Text; - + int startOffset = doc.PositionToOffset(prop.GetterRegion.BeginLine, prop.GetterRegion.BeginColumn); - int endOffset = doc.PositionToOffset(prop.GetterRegion.EndLine, prop.GetterRegion.EndColumn); - + int endOffset = doc.PositionToOffset(prop.GetterRegion.EndLine, prop.GetterRegion.EndColumn); + string code = doc.GetText(startOffset, endOffset - startOffset + 1); - + int index = code.IndexOf("ResourceManager", StringComparison.Ordinal); if (index == -1) { throw new InvalidOperationException("No reference to ResourceManager found in property getter of '" + prop.FullyQualifiedName + "'. Code: '" + code + "'"); } - + index = code.IndexOf("Get", index, StringComparison.Ordinal); if (index == -1) { throw new InvalidOperationException("No call to Get... found in property getter of '" + prop.FullyQualifiedName + "'. Code: '" + code + "'"); } - + index = code.IndexOf(this.StringLiteralDelimiter, index + 1, StringComparison.Ordinal); if (index == -1) { throw new InvalidOperationException("No string delimiter ('" + this.StringLiteralDelimiter + "') found in property getter of '" + prop.FullyQualifiedName + "'. Code: '" + code + "'"); } index += this.StringLiteralDelimiter.Length; - + int endIndex = code.LastIndexOf(this.StringLiteralDelimiter, StringComparison.Ordinal); if (endIndex == -1) { throw new InvalidOperationException("No string terminator ('" + this.StringLiteralDelimiter + "') found in property getter of '" + prop.FullyQualifiedName + "'. Code: '" + code + "'"); } - + string resourceKey = code.Substring(index, endIndex - index); LoggingService.Debug("-> Decoded resource: In: " + resourceFileName + ". Key: " + resourceKey); - + return new ProjectResourceInfo(resourceFileName, resourceKey); } - + /// /// Determines whether the specified class is a generated resource /// class, based on the attached attributes. @@ -167,12 +169,7 @@ namespace ICSharpCode.FormsDesigner.Services return false; } IReturnType generatedCodeAttribute = generatedCodeAttributeClass.DefaultReturnType; - return @class.Attributes.Any( - att => - att.AttributeType.Equals(generatedCodeAttribute) && - att.PositionalArguments.Count == 2 && - String.Equals("System.Resources.Tools.StronglyTypedResourceBuilder", att.PositionalArguments[0] as string, StringComparison.Ordinal) - ); + return @class.Attributes.Any(att => att.AttributeType.Equals(generatedCodeAttribute) && att.PositionalArguments.Count == 2 && String.Equals("System.Resources.Tools.StronglyTypedResourceBuilder", att.PositionalArguments[0] as string, StringComparison.Ordinal)); } } } diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/UIService.cs b/src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/UIService.cs similarity index 100% rename from src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/UIService.cs rename to src/AddIns/DisplayBindings/FormsDesigner/FormsDesigner.AddIn/Services/UIService.cs diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.csproj b/src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.csproj index 4fdae0e584..40ddba9980 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.csproj +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/FormsDesigner.csproj @@ -70,6 +70,8 @@ + + @@ -78,7 +80,6 @@ - diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/IDesignerGenerator.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/IDesignerGenerator.cs index 52678a6263..4a9f516fbd 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/IDesignerGenerator.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/IDesignerGenerator.cs @@ -32,5 +32,6 @@ namespace ICSharpCode.FormsDesigner bool InsertComponentEvent(IComponent component, EventDescriptor edesc, string eventMethodName, string body, out string file, out int position); ICollection GetCompatibleMethods(EventDescriptor edesc); void NotifyFormRenamed(string newName); + CodeDomProvider CodeDomProvider { get; } } } diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/LoggingService.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/LoggingService.cs index 59ec8805e5..7207e6dd95 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/LoggingService.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/LoggingService.cs @@ -31,5 +31,15 @@ namespace ICSharpCode.FormsDesigner { throw new NotImplementedException(); } + + public static void DebugFormatted(string format, params object[] args) + { + throw new NotImplementedException(); + } + + public static void WarnFormatted(string format, params object[] args) + { + throw new NotImplementedException(); + } } } diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/IProjectResourceService.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/IProjectResourceService.cs new file mode 100644 index 0000000000..ae5acd7ff2 --- /dev/null +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/IProjectResourceService.cs @@ -0,0 +1,24 @@ +// 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.CodeDom; +using System.IO; +using System.Linq; + +namespace ICSharpCode.FormsDesigner.Services +{ + public interface IProjectResourceService + { + ProjectResourceInfo GetProjectResource(CodePropertyReferenceExpression propRef); + bool DesignerSupportsProjectResources { get; set; } + string ProjectResourceKey { get; set; } + } + + public interface IMessageService + { + void ShowOutputPad(); + void AppendTextToBuildMessages(string text); + void ShowException(Exception ex, string message); + } +} diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ITypeLocator.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ITypeLocator.cs new file mode 100644 index 0000000000..fc8434cd2b --- /dev/null +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ITypeLocator.cs @@ -0,0 +1,25 @@ +// 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; + +namespace ICSharpCode.FormsDesigner.Services +{ + public struct AssemblyInfo + { + public readonly string FullNameOrPath; + public readonly bool IsInGac; + + public AssemblyInfo(string fullNameOrPath, bool isInGac) + { + this.FullNameOrPath = fullNameOrPath; + this.IsInGac = isInGac; + } + } + + public interface ITypeLocator + { + AssemblyInfo LocateType(string name, out AssemblyInfo[] referencedAssemblies); + bool IsWithinGac(string path); + } +} diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ImageResourceEditor.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ImageResourceEditor.cs index 726eed5484..6f925f3ea6 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ImageResourceEditor.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ImageResourceEditor.cs @@ -33,7 +33,7 @@ namespace ICSharpCode.FormsDesigner.Services if (typeof(Image).IsAssignableFrom(context.PropertyDescriptor.PropertyType) || typeof(Icon).IsAssignableFrom(context.PropertyDescriptor.PropertyType)) { - if (context.GetService(typeof(ProjectResourceService)) is ProjectResourceService) { + if (context.GetService(typeof(IProjectResourceService)) is IProjectResourceService) { return UITypeEditorEditStyle.Modal; } @@ -59,7 +59,7 @@ namespace ICSharpCode.FormsDesigner.Services } } - var prs = provider.GetService(typeof(ProjectResourceService)) as ProjectResourceService; + var prs = provider.GetService(typeof(IProjectResourceService)) as IProjectResourceService; if (prs == null) { return value; } @@ -74,7 +74,7 @@ namespace ICSharpCode.FormsDesigner.Services throw new InvalidOperationException("The required IDictionaryService is not available."); } - var projectResource = dictService.GetValue(ProjectResourceService.ProjectResourceKey + context.PropertyDescriptor.Name) as ProjectResourceInfo; + var projectResource = dictService.GetValue(prs.ProjectResourceKey + context.PropertyDescriptor.Name) as ProjectResourceInfo; IProject project = prs.ProjectContent.Project as IProject; ImageResourceEditorDialog dialog; @@ -95,7 +95,7 @@ namespace ICSharpCode.FormsDesigner.Services if (edsvc.ShowDialog(dialog) == DialogResult.OK) { projectResource = dialog.SelectedProjectResource; if (projectResource != null) { - dictService.SetValue(ProjectResourceService.ProjectResourceKey + context.PropertyDescriptor.Name, projectResource); + dictService.SetValue(prs.ProjectResourceKey + context.PropertyDescriptor.Name, projectResource); // Ensure the resource generator is turned on for the selected resource file. if (project != null) { @@ -114,7 +114,7 @@ namespace ICSharpCode.FormsDesigner.Services return projectResource.OriginalValue; } else { - dictService.SetValue(ProjectResourceService.ProjectResourceKey + context.PropertyDescriptor.Name, null); + dictService.SetValue(prs.ProjectResourceKey + context.PropertyDescriptor.Name, null); return dialog.SelectedResourceValue; } } diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ProjectResourcesComponentCodeDomSerializer.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ProjectResourcesComponentCodeDomSerializer.cs index 60b7168d6e..630e821c19 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ProjectResourcesComponentCodeDomSerializer.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/ProjectResourcesComponentCodeDomSerializer.cs @@ -185,7 +185,7 @@ namespace ICSharpCode.FormsDesigner.Services static ProjectResourceInfo GetProjectResourceFromPropertyReference(IDesignerSerializationManager manager, CodePropertyReferenceExpression propRefSource) { - ProjectResourceService prs = manager.GetService(typeof(ProjectResourceService)) as ProjectResourceService; + IProjectResourceService prs = manager.GetService(typeof(IProjectResourceService)) as IProjectResourceService; if (prs == null) { throw new InvalidOperationException("The required ProjectResourceService is not available."); } @@ -195,11 +195,12 @@ namespace ICSharpCode.FormsDesigner.Services static void StoreResourceInfo(IComponent component, string propertyName, ProjectResourceInfo resourceInfo) { + IProjectResourceService prs = manager.GetService(typeof(IProjectResourceService)) as IProjectResourceService; var dictService = component.Site.GetService(typeof(IDictionaryService)) as IDictionaryService; if (dictService == null) { throw new InvalidOperationException("The required IDictionaryService is not available on component '" + component.ToString() + "'."); } - dictService.SetValue(ProjectResourceService.ProjectResourceKey + propertyName, resourceInfo); + dictService.SetValue(prs.ProjectResourceKey + propertyName, resourceInfo); } #region Default overrides redirecting to baseSerializer diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs index d800d08a60..8612271958 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs @@ -32,13 +32,12 @@ namespace ICSharpCode.FormsDesigner.Services static TypeResolutionService() { ClearMixedAssembliesTemporaryFiles(); - DesignerAssemblies.Add(ProjectContentRegistry.MscorlibAssembly); - DesignerAssemblies.Add(ProjectContentRegistry.SystemAssembly); + DesignerAssemblies.Add(typeof(object).Assembly); + DesignerAssemblies.Add(typeof(System.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")] @@ -69,89 +68,26 @@ namespace ICSharpCode.FormsDesigner.Services string formSourceFileName; + ServiceContainer serviceContainer; + ITypeLocator typeLocator; + /// /// 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); - /* - IProjectContent callingProject; - - /// - /// Gets the project content of the project that created this TypeResolutionService. - /// Returns null when no calling project was specified. - /// - public IProjectContent CallingProject { - get { - if (formSourceFileName != null) { - if (ProjectService.OpenSolution != null) { - IProject p = ProjectService.OpenSolution.FindProjectContainingFile(formSourceFileName); - if (p != null) { - callingProject = ParserService.GetProjectContent(p); - } - } - formSourceFileName = null; - } - return callingProject; - } - }*/ - public TypeResolutionService() { } - public TypeResolutionService(string formSourceFileName) + public TypeResolutionService(string formSourceFileName, ServiceContainer serviceContainer, ITypeLocator typeLocator) { this.formSourceFileName = formSourceFileName; + this.serviceContainer = serviceContainer; + this.typeLocator = typeLocator; } - /* - static readonly Dictionary projectContentsCurrentlyLoadingAssembly = new Dictionary(); - - /// - /// Loads the assembly represented by the project content. Returns null on failure. - /// - public Assembly LoadAssembly(IProjectContent pc) - { - // prevent StackOverflow when project contents have cyclic dependencies - // Very popular example of cyclic dependency: System <-> System.Xml (yes, really!) - if (projectContentsCurrentlyLoadingAssembly.ContainsKey(pc)) - return null; - projectContentsCurrentlyLoadingAssembly.Add(pc, null); - - try { - // load dependencies of current assembly - foreach (IProjectContent rpc in pc.ReferencedContents) { - if (rpc is ParseProjectContent) { - LoadAssembly(rpc); - } else if (rpc is ReflectionProjectContent) { - ReflectionProjectContent rrpc = (ReflectionProjectContent)rpc; - if (rrpc.AssemblyFullName != typeof(object).FullName - && !GacInterop.IsWithinGac(rrpc.AssemblyLocation)) - { - LoadAssembly(rpc); - } - } - } - } finally { - projectContentsCurrentlyLoadingAssembly.Remove(pc); - } - - if (pc.Project != null) { - return LoadAssembly(((IProject)pc.Project).OutputAssemblyFullPath); - } else if (pc is ReflectionProjectContent) { - ReflectionProjectContent rpc = (ReflectionProjectContent)pc; - if (GacInterop.IsWithinGac(rpc.AssemblyLocation)) - return LoadAssembly(new AssemblyName(rpc.AssemblyFullName), false); - else - return LoadAssembly(rpc.AssemblyLocation); - } else { - return null; - } - } - */ - static string GetHash(string fileName) { return Path.GetFileName(fileName).ToLowerInvariant() + File.GetLastWriteTimeUtc(fileName).Ticks.ToString(); @@ -191,6 +127,8 @@ namespace ICSharpCode.FormsDesigner.Services } } + IMessageService messenger = serviceContainer.GetService(typeof(IMessageService)) as IMessageService; + string hash = GetHash(fileName); lock (assemblyDict) { Assembly asm; @@ -223,7 +161,7 @@ namespace ICSharpCode.FormsDesigner.Services asm.LoadModule(Path.GetFileName(fileName), File.ReadAllBytes(fileName)); } } catch (Exception ex) { - MessageService.ShowException(ex, "Error calling linker for netmodule"); + messenger.ShowException(ex, "Error calling linker for netmodule"); } try { File.Delete(tempPath); @@ -234,11 +172,8 @@ namespace ICSharpCode.FormsDesigner.Services // 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" - ); + messenger.ShowOutputPad(); + messenger.AppendTextToBuildMessages("${res:FileUtilityService.ErrorWhileLoading}\r\n" + fileName + "\r\n" + e.Message + "\r\n"); return null; } } catch (FileLoadException e) { @@ -354,28 +289,27 @@ namespace ICSharpCode.FormsDesigner.Services } #endif try { - Type type = Type.GetType(name, false, ignoreCase); if (type == null) { - IProjectContent pc = this.CallingProject; - if (pc != null) { - // find assembly containing type by using SharpDevelop.Dom - IClass foundClass; - if (name.Contains("`")) { - int typeParameterCount; - int.TryParse(name.Substring(name.IndexOf('`') + 1), out typeParameterCount); - foundClass = pc.GetClass(name.Substring(0, name.IndexOf('`')).Replace('+', '.'), typeParameterCount); - } else { - foundClass = pc.GetClass(name.Replace('+', '.'), 0); - } - if (foundClass != null) { - Assembly assembly = LoadAssembly(foundClass.ProjectContent); - if (assembly != null) { - type = assembly.GetType(name, false, ignoreCase); - } - } + AssemblyInfo[] assemblies; + AssemblyInfo assemblyInfo = typeLocator.LocateType(name, out assemblies); + + foreach (AssemblyInfo a in assemblies) { + if (a.IsInGac) + LoadAssembly(new AssemblyName(a.FullNameOrPath), false); + else + LoadAssembly(a.FullNameOrPath); } + + Assembly assembly; + if (assemblyInfo.IsInGac) + assembly = LoadAssembly(new AssemblyName(assemblyInfo.FullNameOrPath), false); + else + assembly = LoadAssembly(assemblyInfo.FullNameOrPath); + + if (assembly != null) + type = assembly.GetType(name, throwOnError, ignoreCase); } // type lookup for typename, assembly, xyz style lookups