Browse Source

Getting AssemblyModel from opened project instead of loading it from compiled assembly in BaseTypesTreeNode. Also taking care that a project's AssemblyModel always has updated references to other assemblies.

pull/80/head
Andreas Weizel 12 years ago
parent
commit
e3e415fc10
  1. 65
      src/Main/Base/Project/Dom/ClassBrowser/BaseTypesTreeNode.cs
  2. 22
      src/Main/Base/Project/Src/Project/CompilableProject.cs
  3. 1
      src/Main/SharpDevelop/Parser/AssemblyParserService.cs

65
src/Main/Base/Project/Dom/ClassBrowser/BaseTypesTreeNode.cs

@ -8,6 +8,7 @@ using ICSharpCode.NRefactory.TypeSystem; @@ -8,6 +8,7 @@ using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{
@ -67,38 +68,56 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -67,38 +68,56 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
ITypeDefinitionModel GetTypeDefinitionModel(ITypeDefinition mainTypeDefinition, ITypeDefinition baseTypeDefinition)
{
ITypeDefinitionModel resolveTypeDefModel = null;
var assemblyParserService = SD.GetService<IAssemblyParserService>();
if (assemblyParserService != null) {
var assemblyFileName = mainTypeDefinition.ParentAssembly.GetRuntimeAssemblyLocation();
if (assemblyFileName != null) {
try {
// Look in the type's AssemblyModel
var assemblyModel = assemblyParserService.GetAssemblyModel(assemblyFileName);
resolveTypeDefModel = assemblyModel.TopLevelTypeDefinitions[baseTypeDefinition.FullTypeName];
if (resolveTypeDefModel != null) {
return resolveTypeDefModel;
var assemblyFileName = mainTypeDefinition.ParentAssembly.GetRuntimeAssemblyLocation();
IAssemblyModel assemblyModel = null;
try {
// Try to get AssemblyModel
IProjectService projectService = SD.GetRequiredService<IProjectService>();
if (projectService.CurrentSolution != null) {
var projectOfAssembly = projectService.CurrentSolution.Projects.FirstOrDefault(p => p.AssemblyModel.Location == assemblyFileName);
if (projectOfAssembly != null) {
// We automatically have an AssemblyModel from project
assemblyModel = projectOfAssembly.AssemblyModel;
}
}
var assemblyParserService = SD.GetService<IAssemblyParserService>();
if (assemblyModel == null) {
if (assemblyParserService != null) {
if (assemblyFileName != null) {
assemblyModel = assemblyParserService.GetAssemblyModel(assemblyFileName);
}
if (assemblyModel.References != null) {
foreach (var referencedAssemblyName in assemblyModel.References) {
DefaultAssemblySearcher searcher = new DefaultAssemblySearcher(assemblyModel.Location);
var resolvedFile = searcher.FindAssembly(referencedAssemblyName);
var referenceAssemblyModel = assemblyParserService.GetAssemblyModel(resolvedFile);
resolveTypeDefModel = referenceAssemblyModel.TopLevelTypeDefinitions[baseTypeDefinition.FullTypeName];
if (resolveTypeDefModel != null) {
return resolveTypeDefModel;
}
}
}
if (assemblyModel != null) {
// Look in the type's AssemblyModel
resolveTypeDefModel = assemblyModel.TopLevelTypeDefinitions[baseTypeDefinition.FullTypeName];
if (resolveTypeDefModel != null) {
return resolveTypeDefModel;
}
// Look at referenced assemblies
if ((assemblyModel.References != null) && (assemblyParserService != null)) {
foreach (var referencedAssemblyName in assemblyModel.References) {
DefaultAssemblySearcher searcher = new DefaultAssemblySearcher(assemblyModel.Location);
var resolvedFile = searcher.FindAssembly(referencedAssemblyName);
var referenceAssemblyModel = assemblyParserService.GetAssemblyModel(resolvedFile);
resolveTypeDefModel = referenceAssemblyModel.TopLevelTypeDefinitions[baseTypeDefinition.FullTypeName];
if (resolveTypeDefModel != null) {
return resolveTypeDefModel;
}
}
} catch (Exception) {
// TODO Can't load the type, what to do?
}
}
} catch (Exception) {
// TODO Can't load the type, what to do?
}
return resolveTypeDefModel;
}
protected override System.Collections.Generic.IComparer<ICSharpCode.TreeView.SharpTreeNode> NodeComparer {
get {
return NodeTextComparer;

22
src/Main/Base/Project/Src/Project/CompilableProject.cs

@ -354,19 +354,24 @@ namespace ICSharpCode.SharpDevelop.Project @@ -354,19 +354,24 @@ namespace ICSharpCode.SharpDevelop.Project
public override IAssemblyModel AssemblyModel {
get {
SD.MainThread.VerifyAccess();
var pc = ProjectContent;
if (assemblyModel == null) {
assemblyModel = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(new ProjectEntityModelContext(this, ".cs"));
var pc = ProjectContent;
if (pc != null && assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).AssemblyName = AssemblyName;
((IUpdateableAssemblyModel)assemblyModel).References = pc.AssemblyReferences
.Select(ResolveReference).Where(r => r != null).ToList();
// Add the already loaded files into the model
foreach (var file in pc.Files) {
((IUpdateableAssemblyModel)assemblyModel).Update(null, file);
}
}
}
// Update references on every access
if (pc != null && assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).References = pc.AssemblyReferences
.Select(ResolveReference).Where(r => r != null).ToList();
}
return assemblyModel;
}
}
@ -391,12 +396,11 @@ namespace ICSharpCode.SharpDevelop.Project @@ -391,12 +396,11 @@ namespace ICSharpCode.SharpDevelop.Project
// OnParseInformationUpdated is called inside a lock, but we don't want to raise the event inside that lock.
// To ensure events are raised in the same order, we always invoke on the main thread.
SD.MainThread.InvokeAsyncAndForget(delegate {
if (assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).Update(args.OldUnresolvedFile, args.NewUnresolvedFile);
// TODO : update references as well?
}
ParseInformationUpdated(null, args);
});
if (assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).Update(args.OldUnresolvedFile, args.NewUnresolvedFile);
}
ParseInformationUpdated(null, args);
});
}
public override event EventHandler<ParseInformationEventArgs> ParseInformationUpdated = delegate {};

1
src/Main/SharpDevelop/Parser/AssemblyParserService.cs

@ -18,6 +18,7 @@ using ICSharpCode.NRefactory.TypeSystem.Implementation; @@ -18,6 +18,7 @@ using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.ClassBrowser;
using ICSharpCode.SharpDevelop.Project;
using Mono.Cecil;
namespace ICSharpCode.SharpDevelop.Parser

Loading…
Cancel
Save