[svn] r7381: nemerle/trunk/ncc/hierarchy/XmlDump.n
pbludov
svnadmin at nemerle.org
Mon Feb 5 04:48:55 CET 2007
Log:
Xml documentation member keys codec.
Author: pbludov
Date: Mon Feb 5 04:48:52 2007
New Revision: 7381
Modified:
nemerle/trunk/ncc/hierarchy/XmlDump.n
Modified: nemerle/trunk/ncc/hierarchy/XmlDump.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/XmlDump.n (original)
+++ nemerle/trunk/ncc/hierarchy/XmlDump.n Mon Feb 5 04:48:52 2007
@@ -33,17 +33,18 @@
using Nemerle.Compiler.Parsetree;
using Nemerle.Utility;
+using System;
using System.Xml;
using System.Text;
namespace Nemerle.Compiler
{
- class XmlDoc {
+ public class XmlDoc {
document : XmlDocument;
docNode : XmlNode;
mutable last_loc : Location;
- public this (comments : Map [Location, string], output : string) {
+ internal this (comments : Map [Location, string], output : string) {
this.Comments = comments;
this.OutputFileName = output;
@@ -59,7 +60,7 @@
OutputFileName : string;
Comments : Map [Location, string];
- public Save () : void {
+ internal Save () : void {
document.Save (OutputFileName);
}
@@ -72,31 +73,9 @@
}
DumpMember (m : IMember) : void {
- def full_name = m.DeclaringType.FullName + "." + m.Name;
- def (prefix, suffix) =
- match (m.MemberKind) {
- | MemberKinds.Field => ("F:", "")
- | MemberKinds.Method | MemberKinds.Constructor =>
- def method = m :> IMethod;
- def parms = List.Map (method.GetParameters (),
- fun (p : Typedtree.Fun_parm) {
- p.ty.SystemType.FullName
- });
- if (!(parms is []))
- ("M:", "(" + Nemerle.Utility.NString.Concat (",", parms) + ")")
- else
- ("M:", "")
-
- | MemberKinds.Property => ("P:", "")
- | MemberKinds.TypeInfo | MemberKinds.NestedType => DumpType (m :> TypeInfo); ("", "")
- | MemberKinds.Event => ("E:", "")
- | _ => ("", "")
- }
- unless (prefix == "" && suffix == "") {
- def member = docNode.AppendChild (CreateMember (prefix + full_name + suffix));
+ def member = docNode.AppendChild (CreateMember (GetKey(m)));
add_comments (member, m);
}
- }
variant XToken
{
@@ -396,13 +375,157 @@
last_loc = curr;
}
- public DumpType (t : TypeInfo) : void {
- def node = docNode.AppendChild (CreateMember ("T:" + t.FullName));
+ internal DumpType (t : TypeInfo) : void {
+ def node = docNode.AppendChild (CreateMember (GetKey(t)));
add_comments (node, t);
def mems = t.GetMembers (BindingFlags.Static %| BindingFlags.Instance %|
BindingFlags.Public %| BindingFlags.NonPublic %|
BindingFlags.DeclaredOnly);
List.Iter (mems, DumpMember);
}
+
+ public static GetKey (m : IMember) : string {
+
+ // Since typical member key has at least four parts
+ // (prefix, declaring type, dot, name) it is good
+ // to use a string builder here.
+ //
+ def sb = StringBuilder ();
+
+ // Append a list of something.
+ // The comma symbol will be inserted between elements.
+ //
+ def appendList['a] (lst : list['a], action : 'a -> void) : void {
+ match (lst) {
+ | Nil => ()
+ | x :: Nil => action (x);
+ | x :: xs =>
+ action (x);
+ ignore (sb.Append (","));
+ appendList (xs, action);
+ }
+ }
+
+ // Append a method parameter type name.
+ //
+ def appendParmTypeName (p : TyVar, m : IMethod) : void {
+
+ // Append a generic parameter type name,
+ // which is an index actually.
+ //
+ def appendStaticTyVarName (tyvar : StaticTyVar) : void {
+ def indexOf ['a] (l : list ['a], a : 'a) : int {
+ def loop (l, a, idx) {
+ match (l) {
+ | h :: t =>
+ if (h.Equals (a))
+ idx
+ else
+ loop (t, a, idx + 1)
+ | [] => -1
+ }
+ }
+
+ loop (l, a, 0)
+ }
+
+ match (indexOf (m.GetHeader ().typarms, tyvar)) {
+ | -1 =>
+ match (indexOf (m.DeclaringType.Typarms, tyvar)) {
+ | -1 => throw ArgumentException ("Unknown type parameter"); // Should never be happen.
+ | x => ignore (sb.Append ("`").Append (x)); // The declaring type generic parameter index.
+ }
+ | x => ignore (sb.Append ("``").Append (x)); // The method generic parameter index.
+ }
+ }
+
+ // Append type name and, optional, generic argument names.
+ //
+ def appendTypeNameAndArgs (typeName : string, args : list[TyVar]) : void {
+ ignore (sb.Append (typeName));
+ unless (args.IsEmpty) {
+ ignore (sb.Append ("{"));
+ appendList (args, e => appendParmTypeName (e, m));
+ ignore (sb.Append ("}"));
+ }
+ }
+
+ match (p.Fix ()) {
+ | Class (tycon, args) => appendTypeNameAndArgs (tycon.FullName, args);
+ | TyVarRef (tyvar) => appendStaticTyVarName (tyvar);
+ | Array (t, rank) =>
+ appendParmTypeName (t, m);
+ if (rank > 1) {
+ ignore (sb.Append ("[0:"));
+ repeat (rank - 1)
+ ignore (sb.Append (",0:"));
+ ignore (sb.Append ("]"));
+ }
+ else
+ ignore (sb.Append ("[]"));
+
+ | Ref (t)
+ | Out (t) => appendParmTypeName (t, m);
+ | Tuple (args) => appendTypeNameAndArgs ("Nemerle.Builtins.Tuple", args);
+ | Fun (from, to) =>
+ def args = match (from.Fix ()) {
+ | Void => [];
+ | Tuple (args) => args;
+ | _ => [from];
+ }
+ match (to.Fix ()) {
+ | Void => appendTypeNameAndArgs ("Nemerle.Builtins.FunctionVoid", args);
+ | _ => appendTypeNameAndArgs ("Nemerle.Builtins.Function", args.Append ([to]));
+ }
+
+ | Void
+ | Intersection => throw InvalidOperationException ("Invalid MType for doc comment");
+ }
+ }
+
+ def appendTypeName (typeInfo : TypeInfo) : void {
+ def tyParmsCount = typeInfo.Typarms.Length;
+
+ ignore (sb.Append (typeInfo.FullName));
+ unless (tyParmsCount == 0)
+ ignore (sb.Append ("`").Append (tyParmsCount));
+ }
+
+ match (m.MemberKind) {
+ | MemberKinds.Field with prefix = "F:"
+ | MemberKinds.Event with prefix = "E:"
+ | MemberKinds.Property with prefix = "P:" =>
+ ignore (sb.Append (prefix));
+ appendTypeName (m.DeclaringType);
+ ignore (sb.Append (".").Append (m.Name.Replace ('.', '#')));
+
+ | MemberKinds.Constructor
+ | MemberKinds.Method =>
+ def method = m :> IMethod;
+ def parms = method.GetParameters ();
+ def tyParmsCount = method.GetHeader ().typarms.Length;
+
+ ignore (sb.Append ("M:"));
+ appendTypeName (method.DeclaringType);
+ ignore (sb.Append (".").Append (m.Name.Replace ('.', '#')));
+
+ unless (tyParmsCount == 0)
+ ignore (sb.Append ("``").Append (tyParmsCount));
+ unless (parms.IsEmpty) {
+ ignore (sb.Append ("("));
+ appendList (parms, p => appendParmTypeName (p.ty, method));
+ ignore (sb.Append (")"));
+ }
+
+ | MemberKinds.TypeInfo
+ | MemberKinds.NestedType =>
+ ignore (sb.Append ("T:"));
+ appendTypeName(m :> TypeInfo);
+
+ | other => throw InvalidOperationException ($"Invalid MemberKinds for doc comment: `$other'");
+ }
+
+ sb.ToString ();
+ }
}
} // end ns
More information about the svn
mailing list