From 2f99cb14ac33e1e1689cd475da4afebacb44b455 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 7 Sep 2012 23:54:05 +0200 Subject: [PATCH] Add FullAssemblyName to IAssembly. --- .../Project/Src/Parser/Parser.cs | 2 +- .../Tests/OverrideCompletionTests.cs | 2 +- .../Document/TextDocument.cs | 2 + .../CSharpProjectContent.cs | 14 ++++++- .../TypeSystem/CSharpAssembly.cs | 4 ++ .../TypeSystem/CecilLoader.cs | 6 +-- .../TypeSystem/IAssembly.cs | 12 +++++- .../DefaultUnresolvedAssembly.cs | 39 ++++++++++++++++++- .../IGlobalAssemblyCacheService.cs | 2 +- .../ParserService/ParseProjectContent.cs | 11 ++++-- .../Base/Project/Src/Util/ExtensionMethods.cs | 12 +++++- .../Parser/GlobalAssemblyCacheService.cs | 5 ++- .../Workbench/WorkbenchStartup.cs | 4 +- 13 files changed, 96 insertions(+), 19 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs index 8427e9ec6f..94d9125869 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs @@ -169,7 +169,7 @@ namespace CSharpBinding.Parser { return new CSharpProjectContent() .AddAssemblyReferences(defaultReferences.Value) - .UpdateProjectContent(null, unresolvedFile) + .AddOrUpdateFiles(unresolvedFile) .CreateCompilation(); } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Tests/OverrideCompletionTests.cs b/src/AddIns/BackendBindings/CSharpBinding/Tests/OverrideCompletionTests.cs index 8b22b89820..593eec1dcb 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Tests/OverrideCompletionTests.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Tests/OverrideCompletionTests.cs @@ -55,7 +55,7 @@ class DerivedClass : BaseClass { textEditor.Document.Text = programStart + "override " + programEnd; textEditor.Caret.Offset = programStart.Length + "override ".Length; var parseInfo = textEditor.CreateParseInformation(); - var pc = new CSharpProjectContent().UpdateProjectContent(null, parseInfo.UnresolvedFile); + var pc = new CSharpProjectContent().AddOrUpdateFiles(parseInfo.UnresolvedFile); pc = pc.AddAssemblyReferences(new[] { Corlib }); var compilation = pc.CreateCompilation(); SD.Services.AddService(typeof(IParserService), MockRepository.GenerateStrictMock()); diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs index b976a3f559..4449677732 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs @@ -374,12 +374,14 @@ namespace ICSharpCode.AvalonEdit.Document } } + /// public void WriteTextTo(System.IO.TextWriter writer) { VerifyAccess(); rope.WriteTo(writer, 0, rope.Length); } + /// public void WriteTextTo(System.IO.TextWriter writer, int offset, int length) { VerifyAccess(); diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs index fccba4622f..5d2112875e 100644 --- a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs +++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs @@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp public class CSharpProjectContent : IProjectContent { string assemblyName; + string fullAssemblyName; string projectFileName; string location; Dictionary unresolvedFiles; @@ -48,6 +49,7 @@ namespace ICSharpCode.NRefactory.CSharp protected CSharpProjectContent(CSharpProjectContent pc) { this.assemblyName = pc.assemblyName; + this.fullAssemblyName = pc.fullAssemblyName; this.projectFileName = pc.projectFileName; this.location = pc.location; this.unresolvedFiles = new Dictionary(pc.unresolvedFiles, Platform.FileNameComparer); @@ -71,6 +73,10 @@ namespace ICSharpCode.NRefactory.CSharp get { return assemblyName; } } + public string FullAssemblyName { + get { return fullAssemblyName; } + } + public string Location { get { return location; } } @@ -128,10 +134,16 @@ namespace ICSharpCode.NRefactory.CSharp return new CSharpProjectContent(this); } + /// + /// Sets both the short and the full assembly names. + /// + /// New full assembly name. public IProjectContent SetAssemblyName(string newAssemblyName) { CSharpProjectContent pc = Clone(); - pc.assemblyName = newAssemblyName; + pc.fullAssemblyName = newAssemblyName; + int pos = newAssemblyName != null ? newAssemblyName.IndexOf(',') : -1; + pc.assemblyName = pos < 0 ? newAssemblyName : newAssemblyName.Substring(0, pos); return pc; } diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs index ec9b9cfeb4..9b0f15a531 100644 --- a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs +++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs @@ -54,6 +54,10 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem get { return projectContent.AssemblyName; } } + public string FullAssemblyName { + get { return projectContent.FullAssemblyName; } + } + public IList AssemblyAttributes { get { return GetAttributes(ref assemblyAttributes, true); diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs index 9a98ed520c..d245cf69ea 100644 --- a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs +++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs @@ -163,7 +163,7 @@ namespace ICSharpCode.NRefactory.TypeSystem moduleAttributes = this.InterningProvider.InternList(moduleAttributes); } - this.currentAssembly = new CecilUnresolvedAssembly(assemblyDefinition.Name.Name, this.DocumentationProvider); + this.currentAssembly = new CecilUnresolvedAssembly(assemblyDefinition.Name, this.DocumentationProvider); currentAssembly.Location = assemblyDefinition.MainModule.FullyQualifiedName; currentAssembly.AssemblyAttributes.AddRange(assemblyAttributes); currentAssembly.ModuleAttributes.AddRange(assemblyAttributes); @@ -253,8 +253,8 @@ namespace ICSharpCode.NRefactory.TypeSystem { readonly IDocumentationProvider documentationProvider; - public CecilUnresolvedAssembly(string assemblyName, IDocumentationProvider documentationProvider) - : base(assemblyName) + public CecilUnresolvedAssembly(AssemblyNameDefinition assemblyName, IDocumentationProvider documentationProvider) + : base(assemblyName.FullName) { Debug.Assert(assemblyName != null); this.documentationProvider = documentationProvider; diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs index 1c98a0498e..c93484300a 100644 --- a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs +++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs @@ -30,7 +30,12 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Gets the assembly name (short name). /// string AssemblyName { get; } - + + /// + /// Gets the full assembly name (including public key token etc.) + /// + string FullAssemblyName { get; } + /// /// Gets the path to the assembly location. /// For projects it is the same as the output path. @@ -81,6 +86,11 @@ namespace ICSharpCode.NRefactory.TypeSystem /// string AssemblyName { get; } + /// + /// Gets the full assembly name (including public key token etc.) + /// + string FullAssemblyName { get; } + /// /// Gets the list of all assembly attributes in the project. /// diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs index d74c1cae84..1111ef638f 100644 --- a/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs +++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs @@ -36,6 +36,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public class DefaultUnresolvedAssembly : AbstractFreezable, IUnresolvedAssembly { string assemblyName; + string fullAssemblyName; IList assemblyAttributes; IList moduleAttributes; Dictionary typeDefinitions = new Dictionary(FullNameAndTypeParameterCountComparer.Ordinal); @@ -51,15 +52,28 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation } } + /// + /// Creates a new unresolved assembly. + /// + /// Full assembly name public DefaultUnresolvedAssembly(string assemblyName) { if (assemblyName == null) throw new ArgumentNullException("assemblyName"); - this.assemblyName = assemblyName; + this.fullAssemblyName = assemblyName; + int pos = assemblyName != null ? assemblyName.IndexOf(',') : -1; + this.assemblyName = pos < 0 ? assemblyName : assemblyName.Substring(0, pos); this.assemblyAttributes = new List(); this.moduleAttributes = new List(); } + /// + /// Gets/Sets the short assembly name. + /// + /// + /// This class handles the short and the full name independently; + /// if you change the short name, you should also change the full name. + /// public string AssemblyName { get { return assemblyName; } set { @@ -69,7 +83,24 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation assemblyName = value; } } - + + /// + /// Gets/Sets the full assembly name. + /// + /// + /// This class handles the short and the full name independently; + /// if you change the full name, you should also change the short name. + /// + public string FullAssemblyName { + get { return fullAssemblyName; } + set { + if (value == null) + throw new ArgumentNullException("value"); + FreezableHelper.ThrowIfFrozen(this); + fullAssemblyName = value; + } + } + string location; public string Location { get { @@ -287,6 +318,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation get { return unresolvedAssembly.AssemblyName; } } + public string FullAssemblyName { + get { return unresolvedAssembly.FullAssemblyName; } + } + public IList AssemblyAttributes { get; private set; } public IList ModuleAttributes { get; private set; } diff --git a/src/Main/Base/Project/Src/Services/ParserService/IGlobalAssemblyCacheService.cs b/src/Main/Base/Project/Src/Services/ParserService/IGlobalAssemblyCacheService.cs index 4bc44ea98d..4f6ddb3d47 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/IGlobalAssemblyCacheService.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/IGlobalAssemblyCacheService.cs @@ -27,6 +27,6 @@ namespace ICSharpCode.SharpDevelop.Parser /// Gets the file name for an assembly stored in the GAC. /// Returns null if the assembly cannot be found. /// - string FindAssemblyInNetGac(DomAssemblyName reference); + FileName FindAssemblyInNetGac(DomAssemblyName reference); } } diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs index 65d77630c7..5ca21bbf9e 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs @@ -105,16 +105,16 @@ namespace ICSharpCode.SharpDevelop.Parser delegate { pc = pc.RemoveAssemblyReferences(pc.AssemblyReferences); int serializableFileCount = 0; - List nonSerializableUnresolvedFiles = new List(); + List nonSerializableUnresolvedFiles = new List(); foreach (var unresolvedFile in pc.Files) { if (IsSerializable(unresolvedFile)) serializableFileCount++; else - nonSerializableUnresolvedFiles.Add(unresolvedFile); + nonSerializableUnresolvedFiles.Add(unresolvedFile.FileName); } // remove non-serializable parsed files if (nonSerializableUnresolvedFiles.Count > 0) - pc = pc.UpdateProjectContent(nonSerializableUnresolvedFiles, null); + pc = pc.RemoveFiles(nonSerializableUnresolvedFiles); if (serializableFileCount > 3) { LoggingService.Debug("Serializing " + serializableFileCount + " files to " + cacheFileName); SaveToCache(cacheFileName, pc); @@ -230,7 +230,10 @@ namespace ICSharpCode.SharpDevelop.Parser // This method is called by the parser service within the parser service (per-file) lock. lock (lockObj) { if (!disposed) { - projectContent = projectContent.UpdateProjectContent(oldFile, newFile); + if (newFile != null) + projectContent = projectContent.AddOrUpdateFiles(newFile); + else + projectContent = projectContent.RemoveFiles(oldFile.FileName); serializedProjectContentIsUpToDate = false; SD.ParserService.InvalidateCurrentSolutionSnapshot(); } diff --git a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs index 432a2d3a8b..98d8a3cc56 100644 --- a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs +++ b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs @@ -188,6 +188,8 @@ namespace ICSharpCode.SharpDevelop /// public static FileName GetReferenceAssemblyLocation(this IAssembly assembly) { + if (assembly == null) + throw new ArgumentNullException("assembly"); return FileName.Create(assembly.UnresolvedAssembly.Location); } @@ -200,7 +202,15 @@ namespace ICSharpCode.SharpDevelop /// public static FileName GetRuntimeAssemblyLocation(this IAssembly assembly) { - #warning Find and use GAC assembly if possible + if (assembly == null) + throw new ArgumentNullException("assembly"); + IUnresolvedAssembly asm = assembly.UnresolvedAssembly; + if (!(asm is IProjectContent)) { + // assembly might be in the GAC + var location = SD.GlobalAssemblyCache.FindAssemblyInNetGac(new DomAssemblyName(assembly.FullAssemblyName)); + if (location != null) + return location; + } return FileName.Create(assembly.UnresolvedAssembly.Location); } diff --git a/src/Main/SharpDevelop/Parser/GlobalAssemblyCacheService.cs b/src/Main/SharpDevelop/Parser/GlobalAssemblyCacheService.cs index ce444030d5..538e1b3bd8 100644 --- a/src/Main/SharpDevelop/Parser/GlobalAssemblyCacheService.cs +++ b/src/Main/SharpDevelop/Parser/GlobalAssemblyCacheService.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; +using ICSharpCode.Core; namespace ICSharpCode.SharpDevelop.Parser { @@ -72,7 +73,7 @@ namespace ICSharpCode.SharpDevelop.Parser /// /// Gets the file name for an assembly stored in the GAC. /// - public string FindAssemblyInNetGac (DomAssemblyName reference) + public FileName FindAssemblyInNetGac (DomAssemblyName reference) { // without public key, it can't be in the GAC if (reference.PublicKeyToken == null) @@ -83,7 +84,7 @@ namespace ICSharpCode.SharpDevelop.Parser var gac = Path.Combine (gac_paths [i], gacs [j]); var file = GetAssemblyFile (reference, prefixes [i], gac); if (File.Exists (file)) - return file; + return FileName.Create(file); } } diff --git a/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs b/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs index 70818736d7..aa4a350062 100644 --- a/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs +++ b/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs @@ -145,8 +145,8 @@ class Test { }"), "test.cs"); // warm up the type system var unresolvedFile = cu.ToTypeSystem(); - var pc = new ICSharpCode.NRefactory.CSharp.CSharpProjectContent().UpdateProjectContent(null, unresolvedFile); - pc = pc.AddAssemblyReferences(new[] { ICSharpCode.NRefactory.TypeSystem.Implementation.MinimalCorlib.Instance }); + var pc = new ICSharpCode.NRefactory.CSharp.CSharpProjectContent().AddOrUpdateFiles(unresolvedFile); + pc = pc.AddAssemblyReferences(ICSharpCode.NRefactory.TypeSystem.Implementation.MinimalCorlib.Instance); var compilation = pc.CreateCompilation(); // warm up the resolver var resolver = new ICSharpCode.NRefactory.CSharp.Resolver.CSharpAstResolver(compilation, cu, unresolvedFile);