// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Refactoring; namespace ICSharpCode.SharpDevelop.Dom { /// /// The context for an entity model. /// This may be a reference to a project, or a compilation provider for a single stand-alone code file. /// public interface IEntityModelContext { /// /// Used for . /// IProject Project { get; } /// /// Used for . /// /// /// The solution snapshot provided to , /// or null if the overload was used. /// ICompilation GetCompilation(); /// /// Returns true if part1 is considered a better candidate for the primary part than part2. /// bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2); /// /// Short name of current assembly. /// string AssemblyName { get; } /// /// Full path and file name of the assembly. Output assembly for projects. /// string Location { get; } /// /// Returns whether this is a valid context (based on a existing and readable definition). /// bool IsValid { get; } } public class ProjectEntityModelContext : IEntityModelContext { readonly IProject project; readonly string primaryCodeFileExtension; public ProjectEntityModelContext(IProject project, string primaryCodeFileExtension) { if (project == null) throw new ArgumentNullException("project"); this.project = project; this.primaryCodeFileExtension = primaryCodeFileExtension; } public string AssemblyName { get { return project.AssemblyName; } } public string Location { get { return project.OutputAssemblyFullPath; } } public IProject Project { get { return project; } } public ICompilation GetCompilation() { return SD.ParserService.GetCompilation(project); } public bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2) { return EntityModelContextUtils.IsBetterPart(part1, part2, primaryCodeFileExtension); } public bool IsValid { get { return true; } } } public class DomAssemblyNameReference : IAssemblyReference { DomAssemblyName name; IAssemblySearcher searcher; public DomAssemblyNameReference(DomAssemblyName name, IAssemblySearcher searcher) { if (name == null) throw new ArgumentNullException("name"); if (searcher == null) throw new ArgumentNullException("searcher"); this.name = name; this.searcher = searcher; } public IAssembly Resolve(ITypeResolveContext context) { return SD.AssemblyParserService.GetAssembly(searcher.FindAssembly(name), true).Resolve(context); } } public class AssemblyEntityModelContext : IEntityModelContext { Lazy compilation; IUnresolvedAssembly mainAssembly; IAssemblyReference[] references; public AssemblyEntityModelContext(IUnresolvedAssembly mainAssembly, IAssemblyReference[] references) { if (mainAssembly == null) throw new ArgumentNullException("mainAssembly"); this.mainAssembly = mainAssembly; this.references = references; this.compilation = new Lazy(() => new SimpleCompilation(mainAssembly, references)); } public string AssemblyName { get { return mainAssembly.AssemblyName; } } public string Location { get { return mainAssembly.Location; } } public ICompilation GetCompilation() { return compilation.Value; } public bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2) { return false; } public IProject Project { get { return null; } } public bool IsValid { get { return true; } } } public static class EntityModelContextUtils { public static bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2, string codeFileExtension) { IUnresolvedFile file1 = part1.UnresolvedFile; IUnresolvedFile file2 = part2.UnresolvedFile; if (file1 != null && file2 == null) return true; if (file1 == null) return false; bool file1HasExtension = file1.FileName.EndsWith(codeFileExtension, StringComparison.OrdinalIgnoreCase); bool file2HasExtension = file2.FileName.EndsWith(codeFileExtension, StringComparison.OrdinalIgnoreCase); if (file1HasExtension && !file2HasExtension) return true; if (!file1HasExtension && file2HasExtension) return false; return file1.FileName.Length < file2.FileName.Length; } } }