mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
5.3 KiB
179 lines
5.3 KiB
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) |
|
// This code is distributed under MIT X11 license (for details please see \doc\license.txt) |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
using System.Diagnostics; |
|
using System.IO; |
|
using System.Xml; |
|
|
|
using ICSharpCode.NRefactory.TypeSystem; |
|
|
|
namespace ICSharpCode.NRefactory.Documentation |
|
{ |
|
/// <summary> |
|
/// Provides documentation from an .xml file (as generated by the Microsoft C# compiler). |
|
/// </summary> |
|
public class XmlDocumentationProvider : IDocumentationProvider |
|
{ |
|
readonly IDictionary<string, string> xmlDocumentation; |
|
|
|
#region Load From File |
|
public XmlDocumentationProvider(string fileName) |
|
{ |
|
if (fileName == null) |
|
throw new ArgumentNullException("fileName"); |
|
this.xmlDocumentation = new Dictionary<string, string>(); |
|
using (XmlTextReader xmlReader = new XmlTextReader(fileName)) { |
|
xmlReader.MoveToContent(); |
|
if (string.IsNullOrEmpty(xmlReader.GetAttribute("redirect"))) { |
|
ReadXmlDoc(xmlReader); |
|
} else { |
|
string redirectionTarget = GetRedirectionTarget(xmlReader.GetAttribute("redirect")); |
|
if (redirectionTarget != null) { |
|
Debug.WriteLine("XmlDoc " + fileName + " is redirecting to " + redirectionTarget); |
|
using (XmlTextReader redirectedXmlReader = new XmlTextReader(redirectionTarget)) { |
|
ReadXmlDoc(redirectedXmlReader); |
|
} |
|
} else { |
|
Debug.WriteLine("XmlDoc " + fileName + " is redirecting to " + xmlReader.GetAttribute("redirect") + ", but that file was not found."); |
|
} |
|
} |
|
} |
|
} |
|
|
|
static string GetRedirectionTarget(string target) |
|
{ |
|
string programFilesDir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); |
|
programFilesDir = AppendDirectorySeparator(programFilesDir); |
|
|
|
string corSysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); |
|
corSysDir = AppendDirectorySeparator(corSysDir); |
|
|
|
return LookupLocalizedXmlDoc(target.Replace("%PROGRAMFILESDIR%", programFilesDir) |
|
.Replace("%CORSYSDIR%", corSysDir)); |
|
} |
|
|
|
static string AppendDirectorySeparator(string dir) |
|
{ |
|
if (dir.EndsWith("\\", StringComparison.Ordinal) || dir.EndsWith("/", StringComparison.Ordinal)) |
|
return dir; |
|
else |
|
return dir + Path.DirectorySeparatorChar; |
|
} |
|
|
|
internal static string LookupLocalizedXmlDoc(string fileName) |
|
{ |
|
string xmlFileName = Path.ChangeExtension(fileName, ".xml"); |
|
string currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName; |
|
string localizedXmlDocFile = GetLocalizedName(xmlFileName, currentCulture); |
|
|
|
Debug.WriteLine("Try find XMLDoc @" + localizedXmlDocFile); |
|
if (File.Exists(localizedXmlDocFile)) { |
|
return localizedXmlDocFile; |
|
} |
|
Debug.WriteLine("Try find XMLDoc @" + xmlFileName); |
|
if (File.Exists(xmlFileName)) { |
|
return xmlFileName; |
|
} |
|
if (currentCulture != "en") { |
|
string englishXmlDocFile = GetLocalizedName(xmlFileName, "en"); |
|
Debug.WriteLine("Try find XMLDoc @" + englishXmlDocFile); |
|
if (File.Exists(englishXmlDocFile)) { |
|
return englishXmlDocFile; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
static string GetLocalizedName(string fileName, string language) |
|
{ |
|
string localizedXmlDocFile = Path.GetDirectoryName(fileName); |
|
localizedXmlDocFile = Path.Combine(localizedXmlDocFile, language); |
|
localizedXmlDocFile = Path.Combine(localizedXmlDocFile, Path.GetFileName(fileName)); |
|
return localizedXmlDocFile; |
|
} |
|
#endregion |
|
|
|
#region Load from XmlReader |
|
public XmlDocumentationProvider(XmlReader reader) |
|
{ |
|
if (reader == null) |
|
throw new ArgumentNullException("reader"); |
|
this.xmlDocumentation = new Dictionary<string, string>(); |
|
ReadXmlDoc(reader); |
|
} |
|
|
|
public XmlDocumentationProvider(IDictionary<string, string> dictionary) |
|
{ |
|
if (dictionary == null) |
|
throw new ArgumentNullException("dictionary"); |
|
this.xmlDocumentation = dictionary; |
|
} |
|
|
|
void ReadXmlDoc(XmlReader reader) |
|
{ |
|
while (reader.Read()) { |
|
if (reader.IsStartElement()) { |
|
switch (reader.LocalName) { |
|
case "members": |
|
ReadMembersSection(reader); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
void ReadMembersSection(XmlReader reader) |
|
{ |
|
while (reader.Read()) { |
|
switch (reader.NodeType) { |
|
case XmlNodeType.EndElement: |
|
if (reader.LocalName == "members") { |
|
return; |
|
} |
|
break; |
|
case XmlNodeType.Element: |
|
if (reader.LocalName == "member") { |
|
string memberAttr = reader.GetAttribute(0); |
|
string innerXml = reader.ReadInnerXml(); |
|
xmlDocumentation[memberAttr] = innerXml; |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
#endregion |
|
|
|
/// <summary> |
|
/// Gets all entries in the documentation file. |
|
/// </summary> |
|
public IDictionary<string, string> XmlDocumentation { |
|
get { return xmlDocumentation; } |
|
} |
|
|
|
public string GetDocumentation(string key) |
|
{ |
|
if (key == null) |
|
throw new ArgumentNullException("key"); |
|
|
|
string result; |
|
if (xmlDocumentation.TryGetValue(key, out result)) |
|
return result; |
|
else |
|
return null; |
|
} |
|
|
|
public string GetDocumentation(IEntity entity) |
|
{ |
|
return GetDocumentation(GetDocumentationKey(entity)); |
|
} |
|
|
|
public static string GetDocumentationKey(IEntity entity) |
|
{ |
|
if (entity == null) |
|
throw new ArgumentNullException("entity"); |
|
throw new NotImplementedException(); |
|
} |
|
} |
|
}
|
|
|