From 491ae3cacf9f6fee322231f9fb1eb88f979e6383 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 8 Dec 2006 20:53:00 +0000 Subject: [PATCH] Force all project contents in a registry to use the same version of .NET assemblies based on the target framework of the project - a .NET 2.0 project referencing .NET 1.1 projects will see .NET 2.0 completion for objects returned by the .NET 1.1 assembly. Fixed bug that caused assemblies referenced by CF projects to always reference .NET 2.0 projects, causing code-completion to fail when the .NET 2.0 registry was not initialized git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2138 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Net1xProjectContentRegistry.cs | 16 ++++++-- .../NetCFProjectContentRegistry.cs | 20 ++++++++-- .../ProjectContent/ProjectContentRegistry.cs | 38 ++++++++++++++++--- 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/Main/Base/Project/Src/Services/ParserService/Net1xProjectContentRegistry.cs b/src/Main/Base/Project/Src/Services/ParserService/Net1xProjectContentRegistry.cs index 78c8b072c2..a9fa9a3e82 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/Net1xProjectContentRegistry.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/Net1xProjectContentRegistry.cs @@ -28,7 +28,7 @@ namespace ICSharpCode.SharpDevelop protected override IProjectContent LoadProjectContent(string itemInclude, string itemFileName) { if (File.Exists(itemFileName)) { - return ParserService.DefaultProjectContentRegistry.GetProjectContentForReference(itemInclude, itemFileName); + return base.LoadProjectContent(itemInclude, itemFileName); } string netPath = Path.Combine(FileUtility.NETFrameworkInstallRoot, DotnetVersion); if (File.Exists(Path.Combine(netPath, "mscorlib.dll"))) { @@ -38,10 +38,18 @@ namespace ICSharpCode.SharpDevelop shortName = shortName.Substring(0, pos); if (File.Exists(Path.Combine(netPath, shortName + ".dll"))) { - return CecilReader.LoadAssembly(Path.Combine(netPath, shortName + ".dll"), this); + ReflectionProjectContent rpc = CecilReader.LoadAssembly(Path.Combine(netPath, shortName + ".dll"), this); + if (rpc != null) { + redirectedAssemblyNames.Add(shortName, rpc.AssemblyFullName); + } + return rpc; } else if (File.Exists(Path.Combine(netPath, shortName))) { // perhaps shortName includes file extension - return CecilReader.LoadAssembly(Path.Combine(netPath, shortName), this); + ReflectionProjectContent rpc = CecilReader.LoadAssembly(Path.Combine(netPath, shortName), this); + if (rpc != null) { + redirectedAssemblyNames.Add(Path.GetFileNameWithoutExtension(shortName), rpc.AssemblyFullName); + } + return rpc; } } else { string message = "Warning: Target .NET Framework version " + DotnetVersion + " is not installed." + Environment.NewLine; @@ -49,7 +57,7 @@ namespace ICSharpCode.SharpDevelop TaskService.BuildMessageViewCategory.AppendText(message); } } - return ParserService.DefaultProjectContentRegistry.GetProjectContentForReference(itemInclude, itemFileName); + return base.LoadProjectContent(itemInclude, itemFileName); } } diff --git a/src/Main/Base/Project/Src/Services/ParserService/NetCFProjectContentRegistry.cs b/src/Main/Base/Project/Src/Services/ParserService/NetCFProjectContentRegistry.cs index 263721ab31..88edc813db 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/NetCFProjectContentRegistry.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/NetCFProjectContentRegistry.cs @@ -32,10 +32,14 @@ namespace ICSharpCode.SharpDevelop return null; } + protected override IProjectContent LoadProjectContent(string itemInclude, string itemFileName) { if (File.Exists(itemFileName)) { - return ParserService.DefaultProjectContentRegistry.GetProjectContentForReference(itemInclude, itemFileName); + // we cannot reuse project contents from the default registry because they would + // reference the wrong mscorlib version, causing code-completion problems + // when a CF application references a CF library + return base.LoadProjectContent(itemInclude, itemFileName); } string netPath = GetInstallFolder(); if (!string.IsNullOrEmpty(netPath) && File.Exists(Path.Combine(netPath, "mscorlib.dll"))) { @@ -45,10 +49,18 @@ namespace ICSharpCode.SharpDevelop shortName = shortName.Substring(0, pos); if (File.Exists(Path.Combine(netPath, shortName + ".dll"))) { - return CecilReader.LoadAssembly(Path.Combine(netPath, shortName + ".dll"), this); + ReflectionProjectContent rpc = CecilReader.LoadAssembly(Path.Combine(netPath, shortName + ".dll"), this); + if (rpc != null) { + redirectedAssemblyNames.Add(shortName, rpc.AssemblyFullName); + } + return rpc; } else if (File.Exists(Path.Combine(netPath, shortName))) { // perhaps shortName includes file extension - return CecilReader.LoadAssembly(Path.Combine(netPath, shortName), this); + ReflectionProjectContent rpc = CecilReader.LoadAssembly(Path.Combine(netPath, shortName), this); + if (rpc != null) { + redirectedAssemblyNames.Add(Path.GetFileNameWithoutExtension(shortName), rpc.AssemblyFullName); + } + return rpc; } } else { string message = "Warning: .NET Compact Framework SDK is not installed." + Environment.NewLine; @@ -56,7 +68,7 @@ namespace ICSharpCode.SharpDevelop TaskService.BuildMessageViewCategory.AppendText(message); } } - return ParserService.DefaultProjectContentRegistry.GetProjectContentForReference(itemInclude, itemFileName); + return base.LoadProjectContent(itemInclude, itemFileName); } } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs index 608c3f3692..47e0a60b68 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs @@ -24,6 +24,11 @@ namespace ICSharpCode.SharpDevelop.Dom internal DomPersistence persistence; internal Dictionary contents = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + /// + /// Redirects short names to long names. Used to redirect .NET libraries to the chosen .NET version + /// + protected Dictionary redirectedAssemblyNames = new Dictionary(); + /// /// Disposes all project contents stored in this registry. /// @@ -167,6 +172,9 @@ namespace ICSharpCode.SharpDevelop.Dom contents["mscorlib"] = mscorlibContent; contents[mscorlibContent.AssemblyFullName] = mscorlibContent; contents[mscorlibContent.AssemblyLocation] = mscorlibContent; + lock (redirectedAssemblyNames) { + redirectedAssemblyNames.Add("mscorlib", mscorlibContent.AssemblyFullName); + } return mscorlibContent; } } @@ -186,6 +194,20 @@ namespace ICSharpCode.SharpDevelop.Dom public virtual IProjectContent GetExistingProjectContent(string itemInclude, string itemFileName) { + if (itemFileName == itemInclude) { + string shortName = itemInclude; + int pos = shortName.IndexOf(','); + if (pos > 0) + shortName = shortName.Substring(0, pos); + + // redirect all references to .NET default assemblies to the .NET version this registry uses + lock (redirectedAssemblyNames) { + if (redirectedAssemblyNames.ContainsKey(shortName)) { + itemFileName = redirectedAssemblyNames[shortName]; + itemInclude = shortName; + } + } + } lock (contents) { if (contents.ContainsKey(itemFileName)) { return contents[itemFileName]; @@ -200,11 +222,9 @@ namespace ICSharpCode.SharpDevelop.Dom public virtual IProjectContent GetProjectContentForReference(string itemInclude, string itemFileName) { lock (contents) { - if (contents.ContainsKey(itemFileName)) { - return contents[itemFileName]; - } - if (contents.ContainsKey(itemInclude)) { - return contents[itemInclude]; + IProjectContent pc = GetExistingProjectContent(itemInclude, itemFileName); + if (pc != null) { + return pc; } LoggingService.Debug("Loading PC for " + itemInclude); @@ -219,7 +239,6 @@ namespace ICSharpCode.SharpDevelop.Dom int time = Environment.TickCount; #endif - IProjectContent pc = null; try { pc = LoadProjectContent(itemInclude, itemFileName); } catch (Exception ex) { @@ -262,6 +281,13 @@ namespace ICSharpCode.SharpDevelop.Dom persistence.SaveProjectContent(pc); } } + if (pc != null) { + // add default .NET assemblies to redirected assemblies (both when loaded from persistence + // and when loaded using Reflection) + lock (redirectedAssemblyNames) { + redirectedAssemblyNames.Add(shortName, pc.AssemblyFullName); + } + } } else { // find real file name for cecil: if (File.Exists(itemFileName)) {