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 13 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;
using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
@ -67,38 +68,56 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
ITypeDefinitionModel GetTypeDefinitionModel(ITypeDefinition mainTypeDefinition, ITypeDefinition baseTypeDefinition) ITypeDefinitionModel GetTypeDefinitionModel(ITypeDefinition mainTypeDefinition, ITypeDefinition baseTypeDefinition)
{ {
ITypeDefinitionModel resolveTypeDefModel = null; ITypeDefinitionModel resolveTypeDefModel = null;
var assemblyParserService = SD.GetService<IAssemblyParserService>(); var assemblyFileName = mainTypeDefinition.ParentAssembly.GetRuntimeAssemblyLocation();
if (assemblyParserService != null) { IAssemblyModel assemblyModel = null;
var assemblyFileName = mainTypeDefinition.ParentAssembly.GetRuntimeAssemblyLocation();
if (assemblyFileName != null) { try {
try { // Try to get AssemblyModel
// Look in the type's AssemblyModel IProjectService projectService = SD.GetRequiredService<IProjectService>();
var assemblyModel = assemblyParserService.GetAssemblyModel(assemblyFileName); if (projectService.CurrentSolution != null) {
resolveTypeDefModel = assemblyModel.TopLevelTypeDefinitions[baseTypeDefinition.FullTypeName]; var projectOfAssembly = projectService.CurrentSolution.Projects.FirstOrDefault(p => p.AssemblyModel.Location == assemblyFileName);
if (resolveTypeDefModel != null) { if (projectOfAssembly != null) {
return resolveTypeDefModel; // 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); if (assemblyModel != null) {
var resolvedFile = searcher.FindAssembly(referencedAssemblyName); // Look in the type's AssemblyModel
var referenceAssemblyModel = assemblyParserService.GetAssemblyModel(resolvedFile); resolveTypeDefModel = assemblyModel.TopLevelTypeDefinitions[baseTypeDefinition.FullTypeName];
resolveTypeDefModel = referenceAssemblyModel.TopLevelTypeDefinitions[baseTypeDefinition.FullTypeName]; if (resolveTypeDefModel != null) {
if (resolveTypeDefModel != null) { return resolveTypeDefModel;
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; return resolveTypeDefModel;
} }
protected override System.Collections.Generic.IComparer<ICSharpCode.TreeView.SharpTreeNode> NodeComparer { protected override System.Collections.Generic.IComparer<ICSharpCode.TreeView.SharpTreeNode> NodeComparer {
get { get {
return NodeTextComparer; return NodeTextComparer;

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

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

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

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

Loading…
Cancel
Save