Browse Source

ClassBrowser: Fixed some problems with COM and project references.

pull/315/head
Andreas Weizel 12 years ago
parent
commit
b088f731db
  1. 14
      src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs
  2. 1
      src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
  3. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  4. 5
      src/Main/Base/Project/Parser/DefaultAssemblySearcher.cs
  5. 68
      src/Main/Base/Project/Parser/ProjectAssemblyReferenceSearcher.cs
  6. 8
      src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs
  7. 53
      src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs
  8. 23
      src/Main/SharpDevelop/Parser/GlobalAssemblyCacheService.cs

14
src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs

@ -80,6 +80,20 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -80,6 +80,20 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
return assemblyTreeNode;
}
public bool GotoAssemblyModel(IAssemblyModel assemblyModel)
{
if (assemblyModel == null)
throw new ArgumentNullException("assemblyModel");
SharpTreeNode assemblyTreeNode = FindAssemblyTreeNode(assemblyModel.FullAssemblyName);
if (assemblyTreeNode != null) {
this.FocusNode(assemblyTreeNode);
return true;
}
return false;
}
public bool GoToEntity(IEntity entity)
{
// Try to find assembly in workspace

1
src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs

@ -15,5 +15,6 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -15,5 +15,6 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
ICollection<IAssemblyList> AssemblyLists { get; }
IAssemblyModel FindAssemblyModel(FileName fileName);
bool GoToEntity(IEntity entity);
bool GotoAssemblyModel(IAssemblyModel assemblyModel);
}
}

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -175,6 +175,7 @@ @@ -175,6 +175,7 @@
<Compile Include="Parser\ISolutionSnapshotWithProjectMapping.cs" />
<Compile Include="Parser\ParseInformation.cs" />
<Compile Include="Parser\ParseInformationEventArgs.cs" />
<Compile Include="Parser\ProjectAssemblyReferenceSearcher.cs" />
<Compile Include="Parser\ProjectContentContainer.cs" />
<Compile Include="Project\Build\BuildDetection.cs" />
<Compile Include="Project\Build\BuildError.cs" />

5
src/Main/Base/Project/Parser/DefaultAssemblySearcher.cs

@ -32,8 +32,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -32,8 +32,7 @@ namespace ICSharpCode.SharpDevelop.Parser
.Where(l => l.Assemblies.Any(a => a.Location == mainAssemblyFileName))
.SelectMany(l => l.Assemblies);
foreach (var asm in relevantClassBrowserAssemblies) {
// TODO I am pretty sure we need the full name here as well...
if (asm.AssemblyName == fullName.ShortName)
if (asm.FullAssemblyName == fullName.FullName)
return asm.Location;
}
@ -51,8 +50,8 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -51,8 +50,8 @@ namespace ICSharpCode.SharpDevelop.Parser
if (File.Exists(fileName))
return fileName;
return null;
}
}
}
}

68
src/Main/Base/Project/Parser/ProjectAssemblyReferenceSearcher.cs

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
// 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.Linq;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Parser
{
/// <summary>
/// Assembly searcher using a project's reference list to resolve assemblies.
/// </summary>
public class ProjectAssemblyReferenceSearcher : IAssemblySearcher
{
IProject project;
public ProjectAssemblyReferenceSearcher(IProject project)
{
if (project == null)
throw new ArgumentNullException("project");
this.project = project;
}
public ICSharpCode.Core.FileName FindAssembly(DomAssemblyName fullName)
{
// Try to find assembly among solution projects
IProjectService projectService = SD.GetRequiredService<IProjectService>();
if (projectService.CurrentSolution != null) {
var projectOfAssembly = projectService.CurrentSolution.Projects.FirstOrDefault(p => p.AssemblyModel.FullAssemblyName == fullName.FullName);
}
ProjectItem projectItem =
project.Items.FirstOrDefault(
item => {
if (item.ItemType == ItemType.COMReference) {
// Special handling for COM references: Their assembly names are prefixed with "Interop."
return fullName.ShortName == "Interop." + item.Include;
}
if ((item.ItemType == ItemType.ProjectReference) && item is ProjectReferenceProjectItem) {
// Special handling for project references: Find assembly name among solution projects
if (projectService.CurrentSolution != null) {
return projectService.CurrentSolution.Projects.Any(p => p.Name == ((ProjectReferenceProjectItem) item).ProjectName);
}
return false;
}
if (item.ItemType == ItemType.Reference) {
return (item.Include == fullName.ShortName);
}
return false;
});
if (projectItem != null) {
if (projectItem is ProjectReferenceProjectItem) {
// This is a project reference, so FileName delivers the project file instead of assembly binary
IProject refProject = ((ProjectReferenceProjectItem) projectItem).ReferencedProject;
if (refProject != null) {
return refProject.OutputAssemblyFullPath;
}
} else {
return projectItem.FileName;
}
}
return null;
}
}
}

8
src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs

@ -166,6 +166,14 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -166,6 +166,14 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
return treeView.GoToEntity(entity);
}
public bool GotoAssemblyModel(IAssemblyModel assemblyModel)
{
// Activate the pad
this.BringToFront();
// Look for assembly node in tree
return treeView.GotoAssemblyModel(assemblyModel);
}
void ProjectServiceCurrentSolutionChanged(object sender, EventArgs e)
{
foreach (var node in treeView.AssemblyLists.OfType<ISolutionAssemblyList>().ToArray())

53
src/Main/SharpDevelop/Dom/ClassBrowser/Commands.cs

@ -71,8 +71,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -71,8 +71,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public override bool CanExecute(object parameter)
{
IAssemblyModel assemblyModel = parameter as IAssemblyModel;
IAssemblyReferenceModel assemblyReferenceModel = parameter as IAssemblyReferenceModel;
return ((assemblyModel != null) && assemblyModel.Context.IsValid) || (assemblyReferenceModel != null);
return ((assemblyModel != null) && assemblyModel.Context.IsValid) || (parameter is IProject) || (parameter is IAssemblyReferenceModel);
}
public override void Execute(object parameter)
@ -81,17 +80,34 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -81,17 +80,34 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
if (classBrowser != null) {
IAssemblyModel assemblyModel = parameter as IAssemblyModel;
if (assemblyModel == null) {
// Node is a project?
IProject project = parameter as IProject;
if (project != null) {
assemblyModel = project.AssemblyModel;
}
}
if (assemblyModel == null) {
// Node is an assembly reference?
IAssemblyReferenceModel assemblyReference = parameter as IAssemblyReferenceModel;
if (assemblyReference == null) {
// Neither assembly model, nor a assembly reference model
return;
if (assemblyReference != null) {
// Model is an assembly reference
IAssemblyParserService assemblyParserService = SD.GetRequiredService<IAssemblyParserService>();
IAssemblySearcher searcher = null;
IEntityModelContext entityModelContext = assemblyReference.ParentAssemblyModel.Context;
if ((entityModelContext != null) && (entityModelContext.Project != null)) {
searcher = new ProjectAssemblyReferenceSearcher(entityModelContext.Project);
} else {
searcher = new DefaultAssemblySearcher(assemblyReference.ParentAssemblyModel.Location);
}
var resolvedFile = searcher.FindAssembly(assemblyReference.AssemblyName);
if (resolvedFile != null) {
assemblyModel = assemblyParserService.GetAssemblyModelSafe(resolvedFile);
} else {
// Assembly file not resolvable
SD.MessageService.ShowWarningFormatted("Could not resolve reference '{0}'.", assemblyReference.AssemblyName.ShortName);
}
}
// Model is an assembly reference
IAssemblyParserService assemblyParserService = SD.GetRequiredService<IAssemblyParserService>();
DefaultAssemblySearcher searcher = new DefaultAssemblySearcher(assemblyReference.ParentAssemblyModel.Location);
var resolvedFile = searcher.FindAssembly(assemblyReference.AssemblyName);
assemblyModel = assemblyParserService.GetAssemblyModelSafe(resolvedFile);
}
if (assemblyModel != null) {
@ -100,6 +116,9 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -100,6 +116,9 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
if (!classBrowser.MainAssemblyList.Assemblies.Contains(assemblyModel))
classBrowser.MainAssemblyList.Assemblies.Add(assemblyModel);
// Bring the node into view
classBrowser.GotoAssemblyModel(assemblyModel);
}
}
}
@ -236,9 +255,15 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -236,9 +255,15 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
return;
}
// TODO Matching item.Include == ShortName fails for interop assemblies, because they are calld "Interop..."
ReferenceProjectItem referenceProjectItem =
project.Items.FirstOrDefault(item => (item.Include == assemblyReferenceModel.AssemblyName.ShortName) && ItemType.ReferenceItemTypes.Contains(item.ItemType)) as ReferenceProjectItem;
ProjectItem referenceProjectItem =
project.Items.FirstOrDefault(
item => {
if (item.ItemType == ItemType.COMReference) {
// Special handling for COM references: Their assembly names are prefixed with "Interop."
return assemblyReferenceModel.AssemblyName.ShortName == "Interop." + item.Include;
}
return (item.Include == assemblyReferenceModel.AssemblyName.ShortName) && ItemType.ReferenceItemTypes.Contains(item.ItemType);
});
if (referenceProjectItem != null) {
ProjectService.RemoveProjectItem(referenceProjectItem.Project, referenceProjectItem);
project.Save();

23
src/Main/SharpDevelop/Parser/GlobalAssemblyCacheService.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Parser
throw new NotImplementedException();
}
public IEnumerable<DomAssemblyName> Assemblies {
public IEnumerable<DomAssemblyName> Assemblies {
get { return GetGacAssemblyFullNames(); }
}
@ -135,8 +135,9 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -135,8 +135,9 @@ namespace ICSharpCode.SharpDevelop.Parser
//
readonly string[] gac_paths = { Fusion.GetGacPath(false), Fusion.GetGacPath(true) };
readonly string[] gacs = { "GAC_MSIL", "GAC_32", "GAC" };
readonly string[] gacs = { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" };
readonly string[] prefixes = { string.Empty, "v4.0_" };
readonly string[] extensions = { ".dll", ".exe" };
/// <summary>
/// Gets the file name for an assembly stored in the GAC.
@ -147,19 +148,21 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -147,19 +148,21 @@ namespace ICSharpCode.SharpDevelop.Parser
if (reference.PublicKeyToken == null)
return null;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < gacs.Length; j++) {
var gac = Path.Combine (gac_paths [i], gacs [j]);
var file = GetAssemblyFile (reference, prefixes [i], gac);
if (File.Exists (file))
return FileName.Create(file);
for (int ipath = 0; ipath < gac_paths.Length; ipath++) {
for (int igac = 0; igac < gacs.Length; igac++) {
for (int iext = 0; iext < extensions.Length; iext++) {
var gac = Path.Combine (gac_paths[ipath], gacs[igac]);
var file = GetAssemblyFile (reference, prefixes[ipath], gac, extensions[iext]);
if (File.Exists (file))
return FileName.Create(file);
}
}
}
return null;
}
static string GetAssemblyFile (DomAssemblyName reference, string prefix, string gac)
static string GetAssemblyFile (DomAssemblyName reference, string prefix, string gac, string ext)
{
var gac_folder = new StringBuilder ()
.Append (prefix)
@ -171,7 +174,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -171,7 +174,7 @@ namespace ICSharpCode.SharpDevelop.Parser
return Path.Combine (
Path.Combine (
Path.Combine (gac, reference.ShortName), gac_folder.ToString ()),
reference.ShortName + ".dll");
reference.ShortName + ext);
}
#endregion
}

Loading…
Cancel
Save