1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Rocks;
namespace Mono.Documentation.Updater.Frameworks
{
public class FrameworkEntry
{
SortedSet<FrameworkTypeEntry> types = new SortedSet<FrameworkTypeEntry> ();
IList<FrameworkEntry> allcachedframeworks;
IList<FrameworkEntry> allframeworks;
ISet<AssemblySet> allAssemblies = new SortedSet<AssemblySet> ();
public int Index = 0;
int _fxCount;
public int FrameworksCount {
get => _fxCount < 1 ? allframeworks.Count : _fxCount;
}
public FrameworkEntry (IList<FrameworkEntry> frameworks, IList<FrameworkEntry> cachedfx) : this(frameworks, -1, cachedfx) {}
public FrameworkEntry (IList<FrameworkEntry> frameworks, int fxCount, IList<FrameworkEntry> cachedFx)
{
allframeworks = frameworks;
if (allframeworks == null)
{
allframeworks = new List<FrameworkEntry> (1);
allframeworks.Add (this);
Index = 0;
allcachedframeworks = allframeworks;
}
else
{
Index = allframeworks.Count;
allcachedframeworks = cachedFx;
}
_fxCount = fxCount;
}
public string Name { get; set; }
public string Version { get; set; }
public string Id { get; set; }
/// <summary>Gets a value indicating whether this <see cref="T:Mono.Documentation.Updater.Frameworks.FrameworkEntry"/> is last framework being processed.</summary>
public bool IsLastFramework {
get => Index == FrameworksCount - 1;
}
/// <param name="assemblyName">should be the assembly name (without version and file extension)</param>
public bool IsLastFrameworkForAssembly(string assemblyName)
{
if (this == Empty) return true;
var retval = this.allcachedframeworks
.Where(f => f.AllProcessedAssemblies
.Any(ass => ass.Assemblies
.Any(a => a.Name.Name.Equals(assemblyName, StringComparison.OrdinalIgnoreCase))))
.ToArray();
if (!retval.Any ()) return false;
var lastListed = retval.Last ();
return lastListed.Name == this.Name;
}
public bool IsLastFrameworkForType(FrameworkTypeEntry typeEntry)
{
if (this == Empty) return true;
var fxlist = this.allcachedframeworks.Where (f => f.FindTypeEntry (typeEntry) != null).ToArray();
if (!fxlist.Any ()) return false;
var lastListed = fxlist.Last ();
return lastListed.Name == this.Name;
}
public string AllFrameworksWithAssembly(string assemblyName)
{
if (this == Empty) return this.Name;
var fxlist = this.allcachedframeworks.Where (f => f.allAssemblies.Any (ass => ass.Assemblies.Any (a => a.Name.Name.Equals (assemblyName, StringComparison.OrdinalIgnoreCase))));
return string.Join (";", fxlist.Select (f => f.Name).ToArray ());
}
public string AllFrameworksWithType(FrameworkTypeEntry typeEntry)
{
if (this == Empty) return this.Name;
var fxlist = this.allcachedframeworks.Where (f => f.FindTypeEntry (typeEntry) != null);
return string.Join (";", fxlist.Select (f => f.Name).ToArray ());
}
string _allFxString = "";
public string AllFrameworksString {
get
{
Lazy<string> fxString = new Lazy<string>(() => string.Join (";", allcachedframeworks.Select (f => f.Name).ToArray ()));
if (!this.IsLastFramework) return fxString.Value;
if (string.IsNullOrWhiteSpace(_allFxString))
{
_allFxString = fxString.Value;
}
return _allFxString;
}
}
public readonly List<Tuple<string,string>> AssemblyNames = new List<Tuple<string, string>> ();
public void AddProcessedAssembly (AssemblyDefinition assembly)
{
AssemblyNames.Add (new Tuple<string, string>(assembly.Name.Name, assembly.Name.Version.ToString()));
}
public IEnumerable<FrameworkEntry> PreviousFrameworks {
get => allframeworks.Where (f => f.Index < this.Index);
}
public ISet<AssemblySet> AllProcessedAssemblies { get => allAssemblies; }
public void AddAssemblySet (AssemblySet assemblySet)
{
allAssemblies.Add (assemblySet);
}
/// <summary>Gets a value indicating whether this <see cref="T:Mono.Documentation.Updater.Frameworks.FrameworkEntry"/> is first framework being processed.</summary>
public bool IsFirstFramework {
get => this.Index == 0;
}
public bool IsFirstFrameworkForType(FrameworkTypeEntry typeEntry)
{
if (this == Empty) return true;
var firstFx = this.allcachedframeworks.FirstOrDefault(f => f.FindTypeEntry(typeEntry) != null);
return firstFx == null || firstFx.Name == this.Name;
}
/// <summary>Only Use in Unit Tests</summary>
public string Replace="";
/// <summary>Only Use in Unit Tests</summary>
public string With ="";
public IEnumerable<DocumentationImporter> Importers { get; set; }
public ISet<FrameworkTypeEntry> Types { get { return this.types; } }
Dictionary<string, FrameworkTypeEntry> typeMap = new Dictionary<string, FrameworkTypeEntry> ();
public FrameworkTypeEntry FindTypeEntry (FrameworkTypeEntry type)
{
return FindTypeEntry (Str(type.Name));
}
/// <param name="name">The value from <see cref="FrameworkTypeEntry.Name"/>.</param>
public FrameworkTypeEntry FindTypeEntry (string name) {
FrameworkTypeEntry entry;
typeMap.TryGetValue (Str(name), out entry);
return entry;
}
public IEnumerable<FrameworkEntry> Frameworks { get { return this.allframeworks; } }
public static readonly FrameworkEntry Empty = new EmptyFrameworkEntry () { Name = "Empty" };
public virtual FrameworkTypeEntry ProcessType (TypeDefinition type)
{
FrameworkTypeEntry entry;
if (!typeMap.TryGetValue (Str(type.FullName), out entry))
{
var docid = DocCommentId.GetDocCommentId (type);
string nstouse = GetNamespace (type);
entry = new FrameworkTypeEntry (this) { Id = Str (docid), Name = Str (type.FullName), Namespace = nstouse };
types.Add (entry);
typeMap.Add (Str (entry.Name), entry);
}
return entry;
}
private string GetNamespace (TypeDefinition type)
{
var nstouse = Str (type.Namespace);
if (string.IsNullOrWhiteSpace (nstouse) && type.DeclaringType != null)
{
return GetNamespace(type.DeclaringType);
}
return nstouse;
}
string Str(string value) {
if (!string.IsNullOrWhiteSpace (Replace))
return value.Replace (Replace, With);
return value;
}
public override string ToString () => Str(this.Name);
class EmptyFrameworkEntry : FrameworkEntry
{
public EmptyFrameworkEntry () : base (null, 1, null) { }
public override FrameworkTypeEntry ProcessType (TypeDefinition type) { return FrameworkTypeEntry.Empty; }
}
}
}
|