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)) {