Browse Source
- split TypeResolutionService - wrap ICSharpCode.Core utilities in IMessageServiceformsdesignerappdomain
14 changed files with 295 additions and 138 deletions
@ -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; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the project content of the project that created this TypeResolutionService.
|
||||||
|
/// Returns null when no calling project was specified.
|
||||||
|
/// </summary>
|
||||||
|
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<IProjectContent, object> projectContentsCurrentlyLoadingAssembly = new Dictionary<IProjectContent, object>(); |
||||||
|
|
||||||
|
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<string> assemblies = new List<string>(); |
||||||
|
|
||||||
|
FindReferencedAssemblies(assemblies, pc); |
||||||
|
|
||||||
|
if (assemblies.Contains(path)) |
||||||
|
assemblies.Remove(path); |
||||||
|
|
||||||
|
referencedAssemblies = assemblies.ToArray(); |
||||||
|
return path; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
referencedAssemblies = new string[0]; |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
void FindReferencedAssemblies(List<string> 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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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 |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of MessageService.
|
||||||
|
/// </summary>
|
||||||
|
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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue