diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/GacReferencePanel.cs b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/GacReferencePanel.cs index b004276833..c3eae488e1 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/GacReferencePanel.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/GacReferencePanel.cs @@ -375,7 +375,8 @@ namespace ICSharpCode.SharpDevelop.Gui } }); - MSBuildInternals.ResolveAssemblyReferences(project, referenceItems.ToArray()); + string mscorlibPath; + MSBuildInternals.ResolveAssemblyReferences(project, referenceItems.ToArray(), out mscorlibPath); WorkbenchSingleton.SafeThreadAsyncCall( delegate { @@ -419,7 +420,8 @@ namespace ICSharpCode.SharpDevelop.Gui } }); - MSBuildInternals.ResolveAssemblyReferences(project, referenceItems.ToArray()); + string mscorlibPath; + MSBuildInternals.ResolveAssemblyReferences(project, referenceItems.ToArray(), out mscorlibPath); foreach (ReferenceProjectItem rpi in referenceItems) { if (string.IsNullOrEmpty(rpi.Redist)) continue; if (!redistNameToRequiredFramework.ContainsKey(rpi.Redist)) { diff --git a/src/Main/Base/Project/Src/Project/CompilableProject.cs b/src/Main/Base/Project/Src/Project/CompilableProject.cs index 0c8bc3e3fb..33458508d6 100644 --- a/src/Main/Base/Project/Src/Project/CompilableProject.cs +++ b/src/Main/Base/Project/Src/Project/CompilableProject.cs @@ -654,22 +654,32 @@ namespace ICSharpCode.SharpDevelop.Project #region Type System volatile ParseProjectContent parseProjectContent; - public override IProjectContent ProjectContent { - get { - if (parseProjectContent == null) { - lock (SyncRoot) { - if (parseProjectContent == null) { - parseProjectContent = new ParseProjectContent(this); - } + protected virtual ParseProjectContent CreateParseProjectContent() + { + return new ParseProjectContent(this); + } + + ParseProjectContent GetParseProjectContent() + { + if (parseProjectContent == null) { + lock (SyncRoot) { + if (parseProjectContent == null) { + parseProjectContent = CreateParseProjectContent(); } } - return parseProjectContent; + } + return parseProjectContent; + } + + public override IProjectContent ProjectContent { + get { + return GetParseProjectContent(); } } public override ITypeResolveContext TypeResolveContext { get { - return new CompositeTypeResolveContext(new ITypeResolveContext[] { this.ProjectContent, MinimalResolveContext.Instance }); + return GetParseProjectContent().TypeResolveContext; } } #endregion diff --git a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs index 20314f7de3..07917ac7c8 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs @@ -137,9 +137,21 @@ namespace ICSharpCode.SharpDevelop.Project } } + volatile string mscorlibPath; + + /// + /// Gets the path to mscorlib. + /// This property is set only after ResolveAssemblyReferences() is called. + /// + public string MscorlibPath { + get { return mscorlibPath; } + } + public override void ResolveAssemblyReferences() { - MSBuildInternals.ResolveAssemblyReferences(this, null); + string mscorlib; + MSBuildInternals.ResolveAssemblyReferences(this, null, out mscorlib); + this.mscorlibPath = mscorlib; } #region CreateProjectItem diff --git a/src/Main/Base/Project/Src/Project/MSBuildInternals.cs b/src/Main/Base/Project/Src/Project/MSBuildInternals.cs index cda8dd5c68..aeea8b1fb7 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildInternals.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildInternals.cs @@ -162,7 +162,7 @@ namespace ICSharpCode.SharpDevelop.Project /// The base project. /// A different set of references to use instead of those in the project. /// Used by the GacReferencePanel. - internal static void ResolveAssemblyReferences(MSBuildBasedProject baseProject, ReferenceProjectItem[] referenceReplacements) + internal static void ResolveAssemblyReferences(MSBuildBasedProject baseProject, ReferenceProjectItem[] referenceReplacements, out string mscorlibPath) { ProjectInstance project = baseProject.CreateProjectInstance(); project.SetProperty("BuildingProject", "false"); @@ -215,18 +215,22 @@ namespace ICSharpCode.SharpDevelop.Project referenceDict[item.Include] = item; } - + mscorlibPath = null; foreach (ProjectItemInstance item in project.GetItems("_ResolveAssemblyReferenceResolvedFiles")) { + DomAssemblyName assemblyName = new DomAssemblyName(item.GetMetadataValue("FusionName")); + string fullPath = FileUtility.GetAbsolutePath(baseProject.Directory, item.GetMetadataValue("Identity")); + string originalInclude = item.GetMetadataValue("OriginalItemSpec"); ReferenceProjectItem reference; if (referenceDict.TryGetValue(originalInclude, out reference)) { reference.AssemblyName = new DomAssemblyName(item.GetMetadataValue("FusionName")); - //string fullPath = item.GetEvaluatedMetadata("FullPath"); is incorrect for relative paths - string fullPath = FileUtility.GetAbsolutePath(baseProject.Directory, item.GetMetadataValue("Identity")); reference.FileName = fullPath; reference.Redist = item.GetMetadataValue("Redist"); LoggingService.Debug("Got information about " + originalInclude + "; fullpath=" + fullPath); reference.DefaultCopyLocalValue = bool.Parse(item.GetMetadataValue("CopyLocal")); + } else if (string.Equals(assemblyName.ShortName, "mscorlib", StringComparison.OrdinalIgnoreCase)) { + LoggingService.Debug("Got information for mscorlib: " + fullPath); + mscorlibPath = fullPath; } else { LoggingService.Warn("Unknown item " + originalInclude); } diff --git a/src/Main/Base/Project/Src/Services/ParserService/AssemblyParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/AssemblyParserService.cs index 3aaa0b5418..1a5ec0360b 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/AssemblyParserService.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/AssemblyParserService.cs @@ -133,6 +133,7 @@ namespace ICSharpCode.SharpDevelop.Parser #region Load Assembly + XML documentation static IProjectContent LoadAssembly(string fileName, CancellationToken cancellationToken) { + LoggingService.Debug("Loading " + fileName); var param = new ReaderParameters(); param.AssemblyResolver = new DummyAssemblyResolver(); AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, param); diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs index 85d849a132..a4c46e846e 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs @@ -9,6 +9,7 @@ using System.Threading; using System.Threading.Tasks; using ICSharpCode.Core; using ICSharpCode.Editor; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; @@ -17,16 +18,18 @@ namespace ICSharpCode.SharpDevelop.Parser { public class ParseProjectContent : SimpleProjectContent, IDisposable { - readonly IProject project; + readonly MSBuildBasedProject project; readonly object lockObj = new object(); + volatile ITypeResolveContext typeResolveContext; bool initializing; bool disposed; - public ParseProjectContent(IProject project) + public ParseProjectContent(MSBuildBasedProject project) { if (project == null) throw new ArgumentNullException("project"); this.project = project; + this.typeResolveContext = MinimalResolveContext.Instance; this.initializing = true; LoadSolutionProjects.AddJob(Initialize, "Loading " + project.Name + "...", GetInitializationWorkAmount()); @@ -42,6 +45,10 @@ namespace ICSharpCode.SharpDevelop.Parser initializing = false; } + public ITypeResolveContext TypeResolveContext { + get { return typeResolveContext; } + } + public override string AssemblyName { get { return project.AssemblyName; } } @@ -75,6 +82,7 @@ namespace ICSharpCode.SharpDevelop.Parser resolveReferencesTask.Wait(); } + initializing = false; } void ParseFiles(ICollection projectItems, IProgressMonitor progressMonitor) @@ -114,6 +122,20 @@ namespace ICSharpCode.SharpDevelop.Parser return System.Threading.Tasks.Task.Factory.StartNew( delegate { project.ResolveAssemblyReferences(); + List contexts = new List(); + string mscorlib = project.MscorlibPath; + if (mscorlib != null && File.Exists(mscorlib)) { + var pc = AssemblyParserService.GetAssembly(FileName.Create(mscorlib), progressMonitor.CancellationToken); + contexts.Add(pc); + } + contexts.Add(this); + foreach (ReferenceProjectItem reference in projectItems.OfType()) { + if (File.Exists(reference.FileName)) { + var pc = AssemblyParserService.GetAssembly(FileName.Create(reference.FileName), progressMonitor.CancellationToken); + contexts.Add(pc); + } + } + this.typeResolveContext = new CompositeTypeResolveContext(contexts); }, progressMonitor.CancellationToken); }