From 0c41adf008f9d629f542769de7302fdd4b7c871f Mon Sep 17 00:00:00 2001 From: Christian Hornung Date: Sun, 3 Dec 2006 15:22:30 +0000 Subject: [PATCH] ResourceToolkit: Added ResourceSetReference as a level of abstraction between manifest resource names (or other resource set names) and actual resource files. The resolvers now return a ResourceSetReference with the resolved resource set name even if the resource file is missing. This may be used in the future to detect missing resource files and to write unit tests for the resolvers without having to create resource files on disk. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2127 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/ResourceToolkit.csproj | 1 + ...NRefactoryResourceCodeCompletionBinding.cs | 18 ++- ...rpCodeCoreResourceCodeCompletionBinding.cs | 23 ++-- .../Src/Gui/UnusedResourceKeysCommands.cs | 2 +- .../Resolver/BclNRefactoryResourceResolver.cs | 78 ++++++------ ...SharpCodeCoreNRefactoryResourceResolver.cs | 26 +--- .../ICSharpCodeCoreResourceResolver.cs | 115 ++++++++++-------- .../Resolver/NRefactoryResourceResolver.cs | 28 +++-- .../Src/Resolver/ResourceResolveResult.cs | 42 ++++--- .../Src/Resolver/ResourceSetReference.cs | 73 +++++++++++ 10 files changed, 249 insertions(+), 157 deletions(-) create mode 100644 src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceSetReference.cs diff --git a/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj b/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj index 6ba21e5c88..f2c80506ec 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj +++ b/src/AddIns/Misc/ResourceToolkit/Project/ResourceToolkit.csproj @@ -70,6 +70,7 @@ + diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs index 6f3dc56c83..8b0170a339 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/AbstractNRefactoryResourceCodeCompletionBinding.cs @@ -7,6 +7,7 @@ using System; using Hornung.ResourceToolkit.Resolver; +using Hornung.ResourceToolkit.ResourceFileContent; using ICSharpCode.NRefactory.PrettyPrinter; using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; @@ -25,8 +26,21 @@ namespace Hornung.ResourceToolkit.CodeCompletion ResourceResolveResult result = ResourceResolverService.Resolve(editor, ch); if (result != null) { - if (result.ResourceFileContent != null) { - editor.ShowCompletionWindow(new ResourceCodeCompletionDataProvider(result.ResourceFileContent, this.OutputVisitor, result.CallingClass != null ? result.CallingClass.Name+"." : null), ch); + IResourceFileContent content; + if ((content = result.ResourceFileContent) != null) { + + // If the resolved resource set is the local ICSharpCode.Core resource set + // (this may happen through the ICSharpCodeCoreNRefactoryResourceResolver), + // we will have to merge in the host resource set (if available) + // for the code completion window. + if (result.ResourceSetReference.ResourceSetName == ICSharpCodeCoreResourceResolver.ICSharpCodeCoreLocalResourceSetName) { + IResourceFileContent hostContent = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceSet(editor.FileName).ResourceFileContent; + if (hostContent != null) { + content = new MergedResourceFileContent(content, new IResourceFileContent[] { hostContent }); + } + } + + editor.ShowCompletionWindow(new ResourceCodeCompletionDataProvider(content, this.OutputVisitor, result.CallingClass != null ? result.CallingClass.Name+"." : null), ch); return true; } } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs index 2b389a05b8..6c6804ba40 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/CodeCompletion/ICSharpCodeCoreResourceCodeCompletionBinding.cs @@ -27,20 +27,17 @@ namespace Hornung.ResourceToolkit.CodeCompletion if (editor.ActiveTextAreaControl.Caret.Offset >= 5 && editor.Document.GetText(editor.ActiveTextAreaControl.Caret.Offset-5, 5) == "${res") { - IResourceFileContent content = null; - string localFile = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreLocalResourceFileName(editor.FileName); - if (localFile != null) { - #if DEBUG - LoggingService.Debug("ResourceToolkit: Found local ICSharpCode.Core resource file: "+localFile); - #endif - content = ResourceFileContentRegistry.GetResourceFileContent(localFile); + IResourceFileContent content = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreLocalResourceSet(editor.FileName).ResourceFileContent; + #if DEBUG + if (content != null) { + LoggingService.Debug("ResourceToolkit: Found local ICSharpCode.Core resource file: "+content.FileName); } + #endif - IResourceFileContent hostContent; - string hostFile = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceFileName(editor.FileName); - if (hostFile != null && (hostContent = ResourceFileContentRegistry.GetResourceFileContent(hostFile)) != null) { + IResourceFileContent hostContent = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceSet(editor.FileName).ResourceFileContent; + if (hostContent != null) { #if DEBUG - LoggingService.Debug("ResourceToolkit: Found host ICSharpCode.Core resource file: "+hostFile); + LoggingService.Debug("ResourceToolkit: Found host ICSharpCode.Core resource file: "+hostContent.FileName); #endif if (content != null) { content = new MergedResourceFileContent(content, new IResourceFileContent[] { hostContent }); @@ -60,8 +57,8 @@ namespace Hornung.ResourceToolkit.CodeCompletion // Provide ${res: as code completion // in an ICSharpCode.Core application - if (ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceFileName(editor.FileName) != null || - ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreLocalResourceFileName(editor.FileName) != null) { + if (ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceSet(editor.FileName).ResourceFileContent != null || + ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreLocalResourceSet(editor.FileName).ResourceFileContent != null) { editor.ShowCompletionWindow(new ICSharpCodeCoreTagCompletionDataProvider(), ch); return true; diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Gui/UnusedResourceKeysCommands.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Gui/UnusedResourceKeysCommands.cs index 80626f9be3..292b2576e8 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Gui/UnusedResourceKeysCommands.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Gui/UnusedResourceKeysCommands.cs @@ -25,7 +25,7 @@ namespace Hornung.ResourceToolkit.Gui IFilterHost host = ((ToolBarCheckBox)this.Owner).Caller as IFilterHost; if (host != null) { if (this.IsChecked) { - this.icSharpCodeCoreHostResourceFileName = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceFileName(null); + this.icSharpCodeCoreHostResourceFileName = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceSet(null).FileName; host.RegisterFilter(this); } else { host.UnregisterFilter(this); diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs index 180e3a9a7c..6b64cbfa7c 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs @@ -167,13 +167,13 @@ namespace Hornung.ResourceToolkit.Resolver // ******************************************************************************************************************************** - #region ResourceFileContent mapping cache + #region ResourceSetReference mapping cache - static Dictionary cachedResourceFileContentMappings; + static Dictionary cachedResourceSetReferenceMappings; static BclNRefactoryResourceResolver() { - cachedResourceFileContentMappings = new Dictionary(new MemberEqualityComparer()); + cachedResourceSetReferenceMappings = new Dictionary(new MemberEqualityComparer()); NRefactoryAstCacheService.CacheEnabledChanged += NRefactoryCacheEnabledChanged; } @@ -181,7 +181,7 @@ namespace Hornung.ResourceToolkit.Resolver { if (!NRefactoryAstCacheService.CacheEnabled) { // Clear cache when disabled. - cachedResourceFileContentMappings.Clear(); + cachedResourceSetReferenceMappings.Clear(); } } @@ -199,48 +199,48 @@ namespace Hornung.ResourceToolkit.Resolver /// static ResourceResolveResult ResolveResource(ResolveResult resolveResult, Expression expr) { - IResourceFileContent rfc = null; + ResourceSetReference rsr = null; MemberResolveResult mrr = resolveResult as MemberResolveResult; if (mrr != null) { - rfc = ResolveResourceFileContent(mrr.ResolvedMember); + rsr = ResolveResourceSet(mrr.ResolvedMember); } else { LocalResolveResult lrr = resolveResult as LocalResolveResult; if (lrr != null) { if (!lrr.IsParameter) { - rfc = ResolveResourceFileContent(lrr.Field); + rsr = ResolveResourceSet(lrr.Field); } } } - if (rfc != null) { + if (rsr != null) { string key = GetKeyFromExpression(expr); // TODO: Add information about return type (of the resource, if present). - return new ResourceResolveResult(resolveResult.CallingClass, resolveResult.CallingMember, null, rfc, key); + return new ResourceResolveResult(resolveResult.CallingClass, resolveResult.CallingMember, null, rsr, key); } return null; } /// - /// Tries to determine the resource file content which is referenced by the + /// Tries to determine the resource set which is referenced by the /// resource manager which is assigned to the specified member. /// /// - /// The IResourceFileContent, if successful, or a null reference, if the + /// The ResourceSetReference, if successful, or a null reference, if the /// specified member is not a resource manager or if the /// resource file cannot be determined. /// - static IResourceFileContent ResolveResourceFileContent(IMember member) + static ResourceSetReference ResolveResourceSet(IMember member) { if (member != null && member.ReturnType != null && member.DeclaringType != null && member.DeclaringType.CompilationUnit != null) { - IResourceFileContent content; - if (!NRefactoryAstCacheService.CacheEnabled || !cachedResourceFileContentMappings.TryGetValue(member, out content)) { + ResourceSetReference rsr; + if (!NRefactoryAstCacheService.CacheEnabled || !cachedResourceSetReferenceMappings.TryGetValue(member, out rsr)) { string declaringFileName = member.DeclaringType.CompilationUnit.FileName; if (declaringFileName != null) { @@ -256,15 +256,15 @@ namespace Hornung.ResourceToolkit.Resolver ResourceManagerInitializationFindVisitor visitor = new ResourceManagerInitializationFindVisitor(member); cu.AcceptVisitor(visitor, null); - if (visitor.FoundFileName != null) { + if (visitor.FoundResourceSet != null) { - content = ResourceFileContentRegistry.GetResourceFileContent(visitor.FoundFileName); + rsr = visitor.FoundResourceSet; - if (NRefactoryAstCacheService.CacheEnabled && content != null) { - cachedResourceFileContentMappings.Add(member, content); + if (NRefactoryAstCacheService.CacheEnabled) { + cachedResourceSetReferenceMappings.Add(member, rsr); } - return content; + return rsr; } @@ -277,7 +277,7 @@ namespace Hornung.ResourceToolkit.Resolver } - return content; + return rsr; } return null; @@ -336,14 +336,14 @@ namespace Hornung.ResourceToolkit.Resolver CompilationUnit compilationUnit; - string foundFileName; + ResourceSetReference foundResourceSet; /// - /// Gets the resource file name which the resource manager accesses, or a null reference if the file could not be determined or does not exist. + /// Gets the resource set which the resource manager accesses, or a null reference if the resource set could not be determined. /// - public string FoundFileName { + public ResourceSetReference FoundResourceSet { get { - return this.foundFileName; + return this.foundResourceSet; } } @@ -439,7 +439,7 @@ namespace Hornung.ResourceToolkit.Resolver public override object TrackedVisit(AssignmentExpression assignmentExpression, object data) { - if (this.FoundFileName == null && // skip if already found to improve performance + if (this.FoundResourceSet == null && // skip if already found to improve performance assignmentExpression.Op == AssignmentOperatorType.Assign && this.PositionAvailable && (!this.isLocalVariable || this.resourceManagerMember.Region.IsInside(this.CurrentNodeStartLocation.Y, this.CurrentNodeStartLocation.X)) // skip if local variable is out of scope ) { @@ -582,14 +582,14 @@ namespace Hornung.ResourceToolkit.Resolver LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found string parameter: '"+pValue+"'"); #endif - string fileName = NRefactoryResourceResolver.GetResourceFileNameByResourceName(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, pValue); - if (fileName != null) { - #if DEBUG - LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: "+fileName); - #endif - this.foundFileName = fileName; - break; + this.foundResourceSet = NRefactoryResourceResolver.GetResourceSetReference(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, pValue); + #if DEBUG + if (this.foundResourceSet.FileName != null) { + LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: "+this.foundResourceSet.FileName); } + #endif + + break; } @@ -606,14 +606,14 @@ namespace Hornung.ResourceToolkit.Resolver LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found typeof(...) parameter, type: '"+trr.ResolvedType.ToString()+"'"); #endif - string fileName = NRefactoryResourceResolver.GetResourceFileNameByResourceName(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, trr.ResolvedType.FullyQualifiedName); - if (fileName != null) { - #if DEBUG - LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: "+fileName); - #endif - this.foundFileName = fileName; - break; + this.foundResourceSet = NRefactoryResourceResolver.GetResourceSetReference(this.resourceManagerMember.DeclaringType.CompilationUnit.FileName, trr.ResolvedType.FullyQualifiedName); + #if DEBUG + if (this.foundResourceSet.FileName != null) { + LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found resource file: "+this.foundResourceSet.FileName); } + #endif + + break; } } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs index d449cf4fb6..2c386e618e 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs @@ -78,31 +78,9 @@ namespace Hornung.ResourceToolkit.Resolver #endif string key = GetKeyFromExpression(expr); - string localResourceFileName = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreLocalResourceFileName(fileName); - string hostResourceFileName = ICSharpCodeCoreResourceResolver.GetICSharpCodeCoreHostResourceFileName(fileName); - IResourceFileContent content = null; - // Merge the local and host resource file contents if available. - - if (!String.IsNullOrEmpty(localResourceFileName)) { - content = ResourceFileContentRegistry.GetResourceFileContent(localResourceFileName); - } - - if (!String.IsNullOrEmpty(hostResourceFileName)) { - if (content == null) { - content = ResourceFileContentRegistry.GetResourceFileContent(hostResourceFileName); - } else { - IResourceFileContent hostContent = ResourceFileContentRegistry.GetResourceFileContent(hostResourceFileName); - if (hostContent != null) { - content = new MergedResourceFileContent(content, new IResourceFileContent[] { hostContent }); - } - } - } - - if (content != null) { - // TODO: Add information about return type (of the resource, if present). - return new ResourceResolveResult(resolveResult.CallingClass, resolveResult.CallingMember, null, content, key); - } + // TODO: Add information about return type (of the resource, if present). + return new ResourceResolveResult(resolveResult.CallingClass, resolveResult.CallingMember, null, ICSharpCodeCoreResourceResolver.ResolveICSharpCodeCoreResourceSet(key, fileName), key); } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs index 8bda00a009..52f71f79a7 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreResourceResolver.cs @@ -126,65 +126,59 @@ namespace Hornung.ResourceToolkit.Resolver #endif } - string resourceFile = ResolveICSharpCodeCoreResourceFileName(key == null ? null : key.ToString(), fileName); + ResourceSetReference resource = ResolveICSharpCodeCoreResourceSet(key == null ? null : key.ToString(), fileName); - if (resourceFile != null) { - // TODO: Add information about callingClass, callingMember, returnType - return new ResourceResolveResult(null, null, null, ResourceFileContentRegistry.GetResourceFileContent(resourceFile), key == null ? null : key.ToString()); - } else { + #if DEBUG + if (resource.FileName == null) { LoggingService.Info("ResourceToolkit: ICSharpCodeCoreResourceResolver: Could not find the ICSharpCode.Core resource file name for the source file '"+fileName+"', key '"+(key == null ? "" : key.ToString())+"'."); } + #endif - return null; + // TODO: Add information about callingClass, callingMember, returnType + return new ResourceResolveResult(null, null, null, resource, key == null ? null : key.ToString()); } // ******************************************************************************************************************************** /// - /// Tries to find the name of the resource file which serves as source for + /// Tries to find the resource set which serves as source for /// the resources accessed by the ICSharpCode.Core. /// /// The resource key to look for. May be null. /// The name of the source code file that contains the reference to the resource. - static string ResolveICSharpCodeCoreResourceFileName(string key, string sourceFileName) + public static ResourceSetReference ResolveICSharpCodeCoreResourceSet(string key, string sourceFileName) { // As there is no easy way to find out the actual location of the resources // based on the source code, we just look in some standard directories. - // Local file (SD addin or standalone application with standard directory structure) - string localFile = GetICSharpCodeCoreLocalResourceFileName(sourceFileName); + // Local set (SD addin or standalone application with standard directory structure) + ResourceSetReference local = GetICSharpCodeCoreLocalResourceSet(sourceFileName); - // Prefer local file, especially if the key is there. - if (localFile != null) { + // Prefer local set, especially if the key is there. + if (local.ResourceFileContent != null) { if (key != null) { - IResourceFileContent localContent = ResourceFileContentRegistry.GetResourceFileContent(localFile); - if (localContent != null) { - if (localContent.ContainsKey(key)) { - return localFile; - } + if (local.ResourceFileContent.ContainsKey(key)) { + return local; } } else { - return localFile; + return local; } } - // Resource file of the host application - string hostFile = GetICSharpCodeCoreHostResourceFileName(sourceFileName); + // Resource set of the host application + ResourceSetReference host = GetICSharpCodeCoreHostResourceSet(sourceFileName); if (key != null) { - if (hostFile != null) { - IResourceFileContent hostContent = ResourceFileContentRegistry.GetResourceFileContent(hostFile); - if (hostContent != null) { - if (hostContent.ContainsKey(key)) { - return hostFile; - } + if (host.ResourceFileContent != null) { + if (host.ResourceFileContent.ContainsKey(key)) { + return host; } } } // Use local file also if the key is not there // (allows adding of a new key) - return localFile == null ? hostFile : localFile; + return local.ResourceFileContent == null ? host : local; } /// @@ -203,43 +197,63 @@ namespace Hornung.ResourceToolkit.Resolver } /// - /// Tries to find the local string resource file used for ICSharpCode.Core resource access. + /// Gets a dummy resource set name used to represent the ICSharpCode.Core + /// resource set of the local application. + /// + public const string ICSharpCodeCoreLocalResourceSetName = "[ICSharpCodeCoreLocalResourceSet]"; + + /// + /// Gets a dummy resource set name used to represent the ICSharpCode.Core + /// resource set of the host application. + /// + public const string ICSharpCodeCoreHostResourceSetName = "[ICSharpCodeCoreHostResourceSet]"; + + static readonly ResourceSetReference EmptyLocalResourceSetReference = new ResourceSetReference(ICSharpCodeCoreLocalResourceSetName, null); + static readonly ResourceSetReference EmptyHostResourceSetReference = new ResourceSetReference(ICSharpCodeCoreHostResourceSetName, null); + + /// + /// Tries to find the local string resource set used for ICSharpCode.Core resource access. /// - /// The name of the source code file which to find the ICSharpCode.Core resource file for. - public static string GetICSharpCodeCoreLocalResourceFileName(string sourceFileName) + /// The name of the source code file which to find the ICSharpCode.Core resource set for. + /// A that describes the referenced resource set. The contained file name may be null if the file cannot be determined. + public static ResourceSetReference GetICSharpCodeCoreLocalResourceSet(string sourceFileName) { IProject project = ProjectFileDictionaryService.GetProjectForFile(sourceFileName); if (project == null || String.IsNullOrEmpty(project.Directory)) { - return null; + return EmptyLocalResourceSetReference; } - string localFile = null; + string localFile; + ResourceSetReference local = null; - if (!NRefactoryAstCacheService.CacheEnabled || !cachedLocalResourceFiles.TryGetValue(project, out localFile)) { + if (!NRefactoryAstCacheService.CacheEnabled || !cachedLocalResourceSets.TryGetValue(project, out local)) { foreach (string relativePath in AddInTree.BuildItems("/AddIns/ResourceToolkit/ICSharpCodeCoreResourceResolver/LocalResourcesLocations", null, false)) { if ((localFile = FindICSharpCodeCoreResourceFile(Path.GetFullPath(Path.Combine(project.Directory, relativePath)))) != null) { + local = new ResourceSetReference(ICSharpCodeCoreLocalResourceSetName, localFile); if (NRefactoryAstCacheService.CacheEnabled) { - cachedLocalResourceFiles.Add(project, localFile); + cachedLocalResourceSets.Add(project, local); } break; } } } - return localFile; + return local ?? EmptyLocalResourceSetReference; } /// - /// Tries to find the string resource file of the host application for ICSharpCode.Core resource access. + /// Tries to find the string resource set of the host application for ICSharpCode.Core resource access. /// - /// The name of the source code file which to find the ICSharpCode.Core resource file for. - public static string GetICSharpCodeCoreHostResourceFileName(string sourceFileName) + /// The name of the source code file which to find the ICSharpCode.Core resource set for. + /// A that describes the referenced resource set. The contained file name may be null if the file cannot be determined. + public static ResourceSetReference GetICSharpCodeCoreHostResourceSet(string sourceFileName) { IProject project = ProjectFileDictionaryService.GetProjectForFile(sourceFileName); - string hostFile = null; + ResourceSetReference host = null; + string hostFile; if (project == null || - !NRefactoryAstCacheService.CacheEnabled || !cachedHostResourceFiles.TryGetValue(project, out hostFile)) { + !NRefactoryAstCacheService.CacheEnabled || !cachedHostResourceSets.TryGetValue(project, out host)) { // Get SD directory using the reference to ICSharpCode.Core string coreAssemblyFullPath = GetICSharpCodeCoreFullPath(project); @@ -256,7 +270,7 @@ namespace Hornung.ResourceToolkit.Resolver } if (coreAssemblyFullPath == null) { - return null; + return EmptyHostResourceSetReference; } #if DEBUG @@ -265,8 +279,9 @@ namespace Hornung.ResourceToolkit.Resolver foreach (string relativePath in AddInTree.BuildItems("/AddIns/ResourceToolkit/ICSharpCodeCoreResourceResolver/HostResourcesLocations", null, false)) { if ((hostFile = FindICSharpCodeCoreResourceFile(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(coreAssemblyFullPath), relativePath)))) != null) { + host = new ResourceSetReference(ICSharpCodeCoreHostResourceSetName, hostFile); if (NRefactoryAstCacheService.CacheEnabled && project != null) { - cachedHostResourceFiles.Add(project, hostFile); + cachedHostResourceSets.Add(project, host); } break; } @@ -274,7 +289,7 @@ namespace Hornung.ResourceToolkit.Resolver } - return hostFile; + return host ?? EmptyHostResourceSetReference; } static string GetICSharpCodeCoreFullPath(IProject sourceProject) @@ -317,15 +332,15 @@ namespace Hornung.ResourceToolkit.Resolver return coreAssemblyFullPath; } - #region ICSharpCode.Core resource file mapping cache + #region ICSharpCode.Core resource set mapping cache - static Dictionary cachedLocalResourceFiles; - static Dictionary cachedHostResourceFiles; + static Dictionary cachedLocalResourceSets; + static Dictionary cachedHostResourceSets; static ICSharpCodeCoreResourceResolver() { - cachedLocalResourceFiles = new Dictionary(); - cachedHostResourceFiles = new Dictionary(); + cachedLocalResourceSets = new Dictionary(); + cachedHostResourceSets = new Dictionary(); NRefactoryAstCacheService.CacheEnabledChanged += NRefactoryCacheEnabledChanged; } @@ -333,8 +348,8 @@ namespace Hornung.ResourceToolkit.Resolver { if (!NRefactoryAstCacheService.CacheEnabled) { // Clear cache when disabled. - cachedLocalResourceFiles.Clear(); - cachedHostResourceFiles.Clear(); + cachedLocalResourceSets.Clear(); + cachedHostResourceSets.Clear(); } } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs index e2dbdda768..340fe0950f 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/NRefactoryResourceResolver.cs @@ -168,9 +168,9 @@ namespace Hornung.ResourceToolkit.Resolver /// /// The name of the source code file which the reference occurs in. /// The manifest resource name to find the resource file for. - /// The name of the file that contains the resources with the specified manifest resource name, or null if the file name cannot be determined. + /// A with the specified resource set name and the name of the file that contains the resources with the specified manifest resource name, or null if the file name cannot be determined. /// The parameter is null. - public static string GetResourceFileNameByResourceName(string sourceFileName, string resourceName) + public static ResourceSetReference GetResourceSetReference(string sourceFileName, string resourceName) { if (resourceName == null) { throw new ArgumentNullException("resourceName"); @@ -186,7 +186,7 @@ namespace Hornung.ResourceToolkit.Resolver // Look for a resource file in the project with the exact name. if ((fileName = FindResourceFileName(Path.Combine(p.Directory, resourceName.Substring(p.RootNamespace.Length+1).Replace('.', Path.DirectorySeparatorChar)))) != null) { - return fileName; + return new ResourceSetReference(resourceName, fileName); } } @@ -248,7 +248,7 @@ namespace Hornung.ResourceToolkit.Resolver // over localized resource file IResourceFileContent rfc = ResourceFileContentRegistry.GetResourceFileContent(fileName); if (rfc.Culture.Equals(CultureInfo.InvariantCulture)) { - return fileName; + return new ResourceSetReference(resourceName, fileName); } } @@ -259,20 +259,22 @@ namespace Hornung.ResourceToolkit.Resolver // Fall back to any found resource file // if no culture-invariant resource file was found if (fileName != null) { - return fileName; + return new ResourceSetReference(resourceName, fileName); } // Find resource files with the same name as the source file // and in the same directory. if ((fileName = FindResourceFileName(possibleSourceFile)) != null) { - return fileName; + return new ResourceSetReference(resourceName, fileName); } } } else { - LoggingService.Info("ResourceToolkit: NRefactoryResourceResolver.GetResourceFileNameByResourceName could not determine the project for the source file '"+(sourceFileName ?? "")+"'."); + #if DEBUG + LoggingService.Info("ResourceToolkit: NRefactoryResourceResolver.GetResourceSetReference could not determine the project for the source file '"+(sourceFileName ?? "")+"'."); + #endif if (sourceFileName != null) { @@ -286,14 +288,14 @@ namespace Hornung.ResourceToolkit.Resolver while (true) { #if DEBUG - LoggingService.Debug("ResourceToolkit: NRefactoryResourceResolver.GetResourceFileNameByResourceName: looking for a resource file like '"+Path.Combine(directory, resourcePart)+"'"); + LoggingService.Debug("ResourceToolkit: NRefactoryResourceResolver.GetResourceSetReference: looking for a resource file like '"+Path.Combine(directory, resourcePart)+"'"); #endif if ((fileName = FindResourceFileName(Path.Combine(directory, resourcePart.Replace('.', Path.DirectorySeparatorChar)))) != null) { - return fileName; + return new ResourceSetReference(resourceName, fileName); } if ((fileName = FindResourceFileName(Path.Combine(directory, resourcePart))) != null) { - return fileName; + return new ResourceSetReference(resourceName, fileName); } if (resourcePart.Contains(".")) { @@ -308,9 +310,11 @@ namespace Hornung.ResourceToolkit.Resolver } - LoggingService.Info("ResourceToolkit: NRefactoryResourceResolver.GetResourceFileNameByResourceName is unable to find a suitable resource file for '"+resourceName+"'"); + #if DEBUG + LoggingService.Info("ResourceToolkit: NRefactoryResourceResolver.GetResourceSetReference is unable to find a suitable resource file for '"+resourceName+"'"); + #endif - return null; + return new ResourceSetReference(resourceName, null); } // ******************************************************************************************************************************** diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs index 0654466b54..2d2a309173 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs @@ -17,15 +17,27 @@ namespace Hornung.ResourceToolkit.Resolver public class ResourceResolveResult : ResolveResult { - IResourceFileContent resourceFileContent; + ResourceSetReference resourceSetReference; string key; /// - /// Gets the of the resource being referenced. + /// Gets the that describes the resource set being referenced. + /// + public ResourceSetReference ResourceSetReference { + get { return this.resourceSetReference; } + } + + /// + /// Gets the for the referenced resource set. + /// May be null. /// public IResourceFileContent ResourceFileContent { get { - return this.resourceFileContent; + if (this.ResourceSetReference == null || + this.ResourceSetReference.FileName == null) { + return null; + } + return this.ResourceSetReference.ResourceFileContent; } } @@ -33,29 +45,27 @@ namespace Hornung.ResourceToolkit.Resolver /// Gets the resource key being referenced. May be null if the key is unknown/not yet typed. /// public string Key { - get { - return this.key; - } + get { return this.key; } } /// /// Gets the resource file name that contains the resource being referenced. - /// Only valid if both and are not null. + /// Only valid if is not null + /// and the contains a valid file name. /// public string FileName { get { - if (this.ResourceFileContent == null || this.Key == null) { - return null; - } - IMultiResourceFileContent mrfc = this.ResourceFileContent as IMultiResourceFileContent; - if (mrfc != null) { + if (mrfc != null && this.Key != null) { return mrfc.GetFileNameForKey(this.Key); - } else { + } else if (this.ResourceFileContent != null) { return this.ResourceFileContent.FileName; + } else if (this.ResourceSetReference != null) { + return this.ResourceSetReference.FileName; } + return null; } } @@ -65,12 +75,12 @@ namespace Hornung.ResourceToolkit.Resolver /// The class that contains the reference to the resource. /// The member that contains the reference to the resource. /// The type of the resource being referenced. - /// The that contains the resource being referenced. + /// The that describes the resource set being referenced. /// The resource key being referenced. - public ResourceResolveResult(IClass callingClass, IMember callingMember, IReturnType returnType, IResourceFileContent resourceFileContent, string key) + public ResourceResolveResult(IClass callingClass, IMember callingMember, IReturnType returnType, ResourceSetReference resourceSetReference, string key) : base(callingClass, callingMember, returnType) { - this.resourceFileContent = resourceFileContent; + this.resourceSetReference = resourceSetReference; this.key = key; } diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceSetReference.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceSetReference.cs new file mode 100644 index 0000000000..c4bebbcf82 --- /dev/null +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceSetReference.cs @@ -0,0 +1,73 @@ +// +// +// +// +// $Revision$ +// + +using System; + +using Hornung.ResourceToolkit.ResourceFileContent; + +namespace Hornung.ResourceToolkit.Resolver +{ + /// + /// Describes a reference to a resource set (this typically means a file, + /// but a resource set reference can exist when the actual file it refers to + /// is missing). + /// + public class ResourceSetReference + { + readonly string resourceSetName; + readonly string fileName; + + /// + /// Gets the resource set name of this reference. + /// This typically corresponds to the manifest resource name. + /// This property never returns null. + /// + public string ResourceSetName { + get { return resourceSetName; } + } + + /// + /// Gets the name of the file that contains the referenced resource set. + /// This property may return null if the file name cannot be + /// determined unambiguously or if the file is missing. + /// + public string FileName { + get { return fileName; } + } + + /// + /// Gets the for the referenced resource set. + /// This property may return null if the file name cannot be + /// determined unambiguously or if the file is missing. + /// + public IResourceFileContent ResourceFileContent { + get { + if (this.FileName == null) return null; + return ResourceFileContentRegistry.GetResourceFileContent(this.FileName); + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The resource set name of the reference. + /// The name of the file that contains the referenced resource set. May be null. + /// The parameter is null. + /// The parameter is empty. + public ResourceSetReference(string resourceSetName, string fileName) + { + if (resourceSetName == null) { + throw new ArgumentNullException("resourceSetName"); + } else if (resourceSetName.Length == 0) { + throw new ArgumentException("The resourceSetName must not be empty.", "resourceSetName"); + } + + this.resourceSetName = resourceSetName; + this.fileName = fileName; + } + } +}