Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mcs/class/monodoc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ RESOURCE_FILES = \
Resources/Lminus.gif \
Resources/Lplus.gif \
Resources/creativecommons.png \
Resources/owner-ios-32.png \
Resources/owner-mac-32.png \
Resources/mdoc-html-format.xsl \
Resources/mdoc-html-utils.xsl \
Resources/mdoc-sections-css.xsl \
Expand Down Expand Up @@ -102,6 +104,8 @@ LIB_MCS_FLAGS = \
/resource:Resources/Lminus.gif,Lminus.gif \
/resource:Resources/Lplus.gif,Lplus.gif \
/resource:Resources/creativecommons.png,creativecommons.png \
/resource:Resources/owner-mac-32.png,owner-mac-32.png \
/resource:Resources/owner-ios-32.png,owner-ios-32.png \
/resource:Resources/mdoc-html-format.xsl,mdoc-html-format.xsl \
/resource:Resources/mdoc-html-utils.xsl,mdoc-html-utils.xsl \
/resource:Resources/mdoc-sections-css.xsl,mdoc-sections-css.xsl \
Expand Down
31 changes: 19 additions & 12 deletions mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public int GenericTypeArgumentsCount {
*/
public bool GenericTypeArgumentsIsNumeric {
get {
return GenericTypeArguments != null && GenericTypeArguments.FirstOrDefault () == null;
return GenericTypeArguments != null && GenericTypeArguments.Any (t => t == null);
}
}

Expand All @@ -116,7 +116,7 @@ public int GenericMemberArgumentsCount {

public bool GenericMemberArgumentsIsNumeric {
get {
return GenericMemberArguments != null && GenericMemberArguments.FirstOrDefault () == null;
return GenericMemberArguments != null && GenericMemberArguments.Any (t => t == null);
}
}

Expand Down Expand Up @@ -232,20 +232,27 @@ void ConstructCRef (StringBuilder sb)
if (DescKind == Kind.Namespace)
return;

sb.Append ('.');
if (!string.IsNullOrEmpty (Namespace))
sb.Append ('.');

sb.Append (TypeName);
if (GenericTypeArguments != null) {
sb.Append ('<');
int i=0;
foreach (var t in GenericTypeArguments) {
if (i > 0) {
sb.Append (",");
if (GenericTypeArgumentsIsNumeric) {
sb.AppendFormat ("`{0}", GenericTypeArgumentsCount);
}
else {
sb.Append ('<');
int i=0;
foreach (var t in GenericTypeArguments) {
if (i > 0) {
sb.Append (",");
}
t.ConstructCRef (sb);

i++;
}
t.ConstructCRef (sb);

i++;
sb.Append ('>');
}
sb.Append ('>');
}
if (NestedType != null) {
sb.Append ('+');
Expand Down
209 changes: 118 additions & 91 deletions mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public static void PopulateTreeFromIndexFile (string indexFilePath,
IDocStorage storage,
Dictionary<string, XElement> nsSummaries,
Func<XElement, string> indexGenerator = null,
IEcmaProviderFileSource fileSource = null)
IEcmaProviderFileSource fileSource = null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PopulateTreeFromIndexFile() taking 8 parameters is a code smell; this is probably a sign that some refactoring is needed, e.g. turning this method into a class and each method parameter into a class property.

It's also odd that EcmaDoc has only static members but is not a static class.

Fortunately, the EcmaDoc type is internal, but still; this is crazy.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as with the mutable static state, this is also another thing that I hesitantly added to avoid a big refactor. The only reason I went forward with it is because the parameters I was adding were optional, and really only useful when being called specifically from mdoc ... so it wouldn't break any other clients that might be using this API.

But you're right that it's a code smell ... if any cause comes up again to modify this code, I will certainly refactor rather than continue adding to the parameter list.

List<string> ownerList = null)
{
fileSource = fileSource ?? DefaultEcmaProviderFileSource.Default;
var root = tree.RootNode;
Expand All @@ -45,115 +46,138 @@ public static void PopulateTreeFromIndexFile (string indexFilePath,
indexGenerator = indexGenerator ?? (_ => resID++.ToString ());

using (var reader = fileSource.GetIndexReader (indexFilePath)) {
reader.ReadToFollowing ("Types");
var types = XElement.Load (reader.ReadSubtree ());

foreach (var ns in types.Elements ("Namespace")) {
var nsName = (string)ns.Attribute ("Name");
nsName = !string.IsNullOrEmpty (nsName) ? nsName : "global";
var nsNode = root.GetOrCreateNode (nsName, "N:" + nsName);

XElement nsElements;
if (!nsSummaries.TryGetValue (nsName, out nsElements))
nsSummaries[nsName] = nsElements = new XElement ("elements",
new XElement ("summary"),
new XElement ("remarks"));
//Add namespace summary and remarks data from file, if available
var nsFileName = fileSource.GetNamespaceXmlPath(asm, nsName);

if(File.Exists(nsFileName)){
var nsEl = fileSource.GetNamespaceElement (nsFileName);

nsElements.Element ("summary").ReplaceWith (nsEl.Descendants ("summary").First ());
nsElements.Element ("remarks").ReplaceWith (nsEl.Descendants ("remarks").First ());
}else{
Console.WriteLine ("Error reading namespace XML for {0} at {1}", nsName, nsFileName);
}

foreach (var type in ns.Elements ("Type")) {
// Add the XML file corresponding to the type to our storage
var id = indexGenerator (type);
string typeFilePath;
var typeDocument = EcmaDoc.LoadTypeDocument (asm, nsName, type.Attribute ("Name").Value, out typeFilePath, fileSource);
if (typeDocument == null)
continue;

// write the document (which may have been modified by the fileSource) to the storage
MemoryStream io = new MemoryStream ();
using (var writer = XmlWriter.Create (io)) {
typeDocument.WriteTo (writer);
reader.MoveToContent ();
while (reader.Read ()) {
if (reader.NodeType == XmlNodeType.Element) {
if (reader.Name == "Owner") {
try {
var owners = XElement.Load (reader.ReadSubtree ());
foreach (var owner in owners.Elements ("Owner")) {
var ownerValue = owner.Value;
ownerList.Add (ownerValue);
}
}
catch (InvalidOperationException ex) {
Console.WriteLine ("Unable to read Owner element from {0}: {1}", indexFilePath, ex);
}
}
io.Seek (0, SeekOrigin.Begin);
storage.Store (id, io);

nsElements.Add (ExtractClassSummary (typeDocument));

var typeCaption = EcmaDoc.GetTypeCaptionFromIndex (type);
var url = idPrefix + id + '#' + typeCaption + '/';
typeCaption = EcmaDoc.GetTypeCaptionFromIndex (type, true);
var typeNode = nsNode.CreateNode (typeCaption, url);

// Add meta "Members" node
typeNode.CreateNode ("Members", "*");
var membersNode = typeDocument.Root.Element ("Members");
if (membersNode == null || !membersNode.Elements ().Any ())
continue;
var members = membersNode
.Elements ("Member")
.ToLookup (EcmaDoc.GetMemberType);

foreach (var memberType in members) {
// We pluralize the member type to get the caption and take the first letter as URL
var node = typeNode.CreateNode (EcmaDoc.PluralizeMemberType (memberType.Key), memberType.Key[0].ToString ());
var memberIndex = 0;

var isCtors = memberType.Key[0] == 'C';

// We do not escape much member name here
foreach (var memberGroup in memberType.GroupBy (m => MakeMemberCaption (m, isCtors))) {
if (memberGroup.Count () > 1) {
// Generate overload
var overloadCaption = MakeMemberCaption (memberGroup.First (), false);
var overloadNode = node.CreateNode (overloadCaption, overloadCaption);
foreach (var member in memberGroup)
overloadNode.CreateNode (MakeMemberCaption (member, true), (memberIndex++).ToString ());
overloadNode.Sort ();
} else {
// We treat constructor differently by showing their argument list in all cases
node.CreateNode (MakeMemberCaption (memberGroup.First (), isCtors), (memberIndex++).ToString ());
else if (reader.Name == "Types") {

XElement types = XElement.Load (reader.ReadSubtree ());

foreach (var ns in types.Elements ("Namespace")) {
var nsName = (string)ns.Attribute ("Name");
var nsPath = (string)ns.Attribute ("Path");
nsName = !string.IsNullOrEmpty (nsName) ? nsName : "global";
nsPath = !string.IsNullOrEmpty (nsPath) ? nsPath : nsName;
var nsNode = root.GetOrCreateNode (nsName, "N:" + nsName);

XElement nsElements;
if (!nsSummaries.TryGetValue (nsName, out nsElements))
nsSummaries[nsName] = nsElements = new XElement ("elements",
new XElement ("summary"),
new XElement ("remarks"));
//Add namespace summary and remarks data from file, if available
var nsFileName = fileSource.GetNamespaceXmlPath(asm, nsPath);

if(File.Exists(nsFileName)){
var nsEl = fileSource.GetNamespaceElement (nsFileName);

nsElements.Element ("summary").ReplaceWith (nsEl.Descendants ("summary").First ());
nsElements.Element ("remarks").ReplaceWith (nsEl.Descendants ("remarks").First ());
}else{
Console.WriteLine ("Error reading namespace XML for {0} at {1}", nsName, nsFileName);
}

foreach (var type in ns.Elements ("Type")) {
// Add the XML file corresponding to the type to our storage
var id = indexGenerator (type);

string typeFilePath;
var typeDocument = EcmaDoc.LoadTypeDocument (asm, nsName, nsPath, type.Attribute ("Name").Value, out typeFilePath, fileSource);
if (typeDocument == null)
continue;

// write the document (which may have been modified by the fileSource) to the storage
MemoryStream io = new MemoryStream ();
using (var writer = XmlWriter.Create (io)) {
typeDocument.WriteTo (writer);
}
io.Seek (0, SeekOrigin.Begin);
storage.Store (id, io);

nsElements.Add (ExtractClassSummary (typeDocument));

var typeCaption = EcmaDoc.GetTypeCaptionFromIndex (type);
var url = idPrefix + id + '#' + typeCaption + '/';
typeCaption = EcmaDoc.GetTypeCaptionFromIndex (type, true);
var typeNode = nsNode.CreateNode (typeCaption, url);

// Add meta "Members" node
typeNode.CreateNode ("Members", "*");
var membersNode = typeDocument.Root.Element ("Members");
if (membersNode == null || !membersNode.Elements ().Any ())
continue;
var members = membersNode
.Elements ("Member")
.ToLookup (EcmaDoc.GetMemberType);

foreach (var memberType in members) {
// We pluralize the member type to get the caption and take the first letter as URL
var node = typeNode.CreateNode (EcmaDoc.PluralizeMemberType (memberType.Key), memberType.Key[0].ToString ());
var memberIndex = 0;

var isCtors = memberType.Key[0] == 'C';

// We do not escape much member name here
foreach (var memberGroup in memberType.GroupBy (m => MakeMemberCaption (m, isCtors))) {
if (memberGroup.Count () > 1) {
// Generate overload
var overloadCaption = MakeMemberCaption (memberGroup.First (), false);
var overloadNode = node.CreateNode (overloadCaption, overloadCaption);
foreach (var member in memberGroup)
overloadNode.CreateNode (MakeMemberCaption (member, true), (memberIndex++).ToString ());
overloadNode.Sort ();
} else {
// We treat constructor differently by showing their argument list in all cases
node.CreateNode (MakeMemberCaption (memberGroup.First (), isCtors), (memberIndex++).ToString ());
}
}
node.Sort ();
}
}


nsNode.Sort ();
}
node.Sort ();
root.Sort ();
}
}

nsNode.Sort ();
}
root.Sort ();
}
}

// Utility methods

public static XDocument LoadTypeDocument (string basePath, string nsName, string typeName, IEcmaProviderFileSource fileSource = null)
public static XDocument LoadTypeDocument (string basePath, string nsName, string nsPath, string typeName, IEcmaProviderFileSource fileSource = null)
{
string dummy;
return LoadTypeDocument (basePath, nsName, typeName, out dummy, fileSource ?? DefaultEcmaProviderFileSource.Default);
return LoadTypeDocument (basePath, nsName, nsPath, typeName, out dummy, fileSource ?? DefaultEcmaProviderFileSource.Default);
}

public static XDocument LoadTypeDocument (string basePath, string nsName, string typeName, out string finalPath, IEcmaProviderFileSource fileSource = null)
public static XDocument LoadTypeDocument (string basePath, string nsName, string nsPath, string typeName, out string finalPath, IEcmaProviderFileSource fileSource = null)
{
fileSource = fileSource ?? DefaultEcmaProviderFileSource.Default;

finalPath = fileSource.GetTypeXmlPath (basePath, nsName, typeName);
finalPath = fileSource.GetTypeXmlPath (basePath, nsPath, typeName);
if (!File.Exists (finalPath)) {
Console.Error.WriteLine ("Warning: couldn't process type file `{0}' as it doesn't exist", finalPath);
return null;
}

XDocument doc = null;
try {
doc = fileSource.GetTypeDocument(finalPath);
doc = fileSource.GetTypeDocument (finalPath, nsName);
} catch (Exception e) {
Console.WriteLine ("Document `{0}' is unparsable, {1}", finalPath, e.ToString ());
}
Expand Down Expand Up @@ -578,16 +602,19 @@ internal static string MakeOperatorSignature (XElement member, out string member

static XElement ExtractClassSummary (XDocument typeDoc)
{
string name = typeDoc.Root.Attribute("Name").Value;
string fullName = typeDoc.Root.Attribute("FullName").Value;
string assemblyName = typeDoc.Root.Element("AssemblyInfo") != null ? typeDoc.Root.Element("AssemblyInfo").Element("AssemblyName").Value : string.Empty;
var docs = typeDoc.Root.Element("Docs");
var summary = docs.Element("summary") ?? new XElement("summary");
var remarks = docs.Element("remarks") ?? new XElement("remarks");
string name = typeDoc.Root.Attribute ("Name").Value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid whitespace changes. This patch is huge enough as it is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:/ I know, sorry ... it just seemed such an egregious break from the coding standards that had just made it through to master. Is it verboten to do whitespace changes ever? Would it be better to do have a "whitespace only" pull request to fix things like this? or better to just leave it as is until that code gets rewritten entirely at some point?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with whitespace changes is that they pollute history. You can't "just" do git blame to see when the line was added, because now the line was changed for purely whitespace reasons.

Thus, instead of:

git blame file.cs

it's:

git blame file.cs
# get commit of line change; see it's just a whitespace change
git blame COMMIT^ file.cs
# repeat

and if file was ever MOVED, then git blame COMMIT^ file.cs fails because the path is wrong, and this is MADNESS.

Whitespace changes are evil if you ever need to dig through code history to figure out why a change was done.

Is it verboten to do whitespace changes ever?

Let's go with "yes". You can do whitespace changes in addition to other changes which impact the same line, e.g. if a variable name changes and thus the line would change anyway, then additional whitespace changes to that line would be fine. (Though because of the complications in viewing history, renaming a variable "just because" is also something to be discouraged.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok ... I will be very much more careful with this in the future. Thanks for the explanation :)

string fullName = typeDoc.Root.Attribute ("FullName").Value;
string assemblyName = typeDoc.Root.Element ("AssemblyInfo") != null ? typeDoc.Root.Element("AssemblyInfo").Element("AssemblyName").Value : string.Empty;
string owners = typeDoc.Root.Attribute ("owner") != null ? typeDoc.Root.Attribute ("owner").Value : string.Empty;
var docs = typeDoc.Root.Element ("Docs");
var summary = docs.Element ("summary") ?? new XElement ("summary");
var remarks = docs.Element ("remarks") ?? new XElement ("remarks");

return new XElement ("class",
new XAttribute ("name", name ?? string.Empty),
new XAttribute ("fullname", fullName ?? string.Empty),
new XAttribute ("assembly", assemblyName ?? string.Empty),
new XAttribute ("owner", owners),
summary,
remarks);
}
Expand Down
Loading