Browse Source
- split TypeResolutionService - wrap ICSharpCode.Core utilities in IMessageServiceformsdesignerappdomain
14 changed files with 295 additions and 138 deletions
@ -0,0 +1,126 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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