Emit correct sequence info for iterators
[mono.git] / mcs / mcs / doc.cs
index 24db11a07e8b1e2265d5df16365d207b9645983b..19340bf6c1e3c6241c6e05ef14d2efc8a46208df 100644 (file)
@@ -1,12 +1,14 @@
 //
 // doc.cs: Support for XML documentation comment.
 //
-// Author:
+// Authors:
 //     Atsushi Enomoto <atsushi@ximian.com>
+//  Marek Safar (marek.safar@gmail.com>
 //
 // Dual licensed under the terms of the MIT X11 or GNU GPL
 //
 // Copyright 2004 Novell, Inc.
+// Copyright 2011 Xamarin Inc
 //
 //
 
@@ -17,76 +19,72 @@ using System.Text;
 using System.Xml;
 using System.Linq;
 
-
-namespace Mono.CSharp {
-
+namespace Mono.CSharp
+{
        //
-       // Support class for XML documentation.
+       // Implements XML documentation generation.
        //
-       static class DocUtil
+       class DocumentationBuilder
        {
-               // TypeContainer
-
                //
-               // Generates xml doc comments (if any), and if required,
-               // handle warning report.
+               // Used to create element which helps well-formedness checking.
                //
-               internal static void GenerateTypeDocComment (TypeContainer t,
-                       DeclSpace ds, Report Report)
-               {
-                       GenerateDocComment (t, ds, Report);
+               readonly XmlDocument XmlDocumentation;
 
-                       if (t.DefaultStaticConstructor != null)
-                               t.DefaultStaticConstructor.GenerateDocComment (t);
+               readonly ModuleContainer module;
+               readonly ModuleContainer doc_module;
 
-                       if (t.InstanceConstructors != null)
-                               foreach (Constructor c in t.InstanceConstructors)
-                                       c.GenerateDocComment (t);
+               //
+               // The output for XML documentation.
+               //
+               XmlWriter XmlCommentOutput;
 
-                       if (t.Types != null)
-                               foreach (TypeContainer tc in t.Types)
-                                       tc.GenerateDocComment (t);
+               static readonly string line_head = Environment.NewLine + "            ";
 
-                       if (t.Constants != null)
-                               foreach (Const c in t.Constants)
-                                       c.GenerateDocComment (t);
+               //
+               // Stores XmlDocuments that are included in XML documentation.
+               // Keys are included filenames, values are XmlDocuments.
+               //
+               Dictionary<string, XmlDocument> StoredDocuments = new Dictionary<string, XmlDocument> ();
 
-                       if (t.Fields != null)
-                               foreach (FieldBase f in t.Fields)
-                                       f.GenerateDocComment (t);
+               public DocumentationBuilder (ModuleContainer module)
+               {
+                       doc_module = new ModuleContainer (module.Compiler);
+                       doc_module.DocumentationBuilder = this;
 
-                       if (t.Events != null)
-                               foreach (Event e in t.Events)
-                                       e.GenerateDocComment (t);
+                       this.module = module;
+                       XmlDocumentation = new XmlDocument ();
+                       XmlDocumentation.PreserveWhitespace = false;
+               }
 
-                       if (t.Indexers != null)
-                               foreach (Indexer ix in t.Indexers)
-                                       ix.GenerateDocComment (t);
+               Report Report {
+                       get {
+                               return module.Compiler.Report;
+                       }
+               }
 
-                       if (t.Properties != null)
-                               foreach (Property p in t.Properties)
-                                       p.GenerateDocComment (t);
+               public MemberName ParsedName {
+                       get; set;
+               }
 
-                       if (t.Methods != null)
-                               foreach (MethodOrOperator m in t.Methods)
-                                       m.GenerateDocComment (t);
+               public List<DocumentationParameter> ParsedParameters {
+                       get; set;
+               }
 
-                       if (t.Operators != null)
-                               foreach (Operator o in t.Operators)
-                                       o.GenerateDocComment (t);
+               public TypeExpression ParsedBuiltinType {
+                       get; set;
                }
 
-               // MemberCore
-               private static readonly string line_head =
-                       Environment.NewLine + "            ";
+               public Operator.OpType? ParsedOperator {
+                       get; set;
+               }
 
-               private static XmlNode GetDocCommentNode (MemberCore mc,
-                       string name, Report Report)
+               XmlNode GetDocCommentNode (MemberCore mc, string name)
                {
                        // FIXME: It could be even optimizable as not
                        // to use XmlDocument. But anyways the nodes
                        // are not kept in memory.
-                       XmlDocument doc = mc.Compiler.Settings.Documentation.XmlDocumentation;
+                       XmlDocument doc = XmlDocumentation;
                        try {
                                XmlElement el = doc.CreateElement ("member");
                                el.SetAttribute ("name", name);
@@ -110,9 +108,10 @@ namespace Mono.CSharp {
                                        line_head, split, 0, j);
                                return el;
                        } catch (Exception ex) {
-                               Report.Warning (1570, 1, mc.Location, "XML comment on `{0}' has non-well-formed XML ({1})", name, ex.Message);
-                               XmlComment com = doc.CreateComment (String.Format ("FIXME: Invalid documentation markup was found for member {0}", name));
-                               return com;
+                               Report.Warning (1570, 1, mc.Location, "XML documentation comment on `{0}' is not well-formed XML markup ({1})",
+                                       mc.GetSignatureForError (), ex.Message);
+
+                               return doc.CreateComment (String.Format ("FIXME: Invalid documentation markup was found for member {0}", name));
                        }
                }
 
@@ -120,58 +119,56 @@ namespace Mono.CSharp {
                // Generates xml doc comments (if any), and if required,
                // handle warning report.
                //
-               internal static void GenerateDocComment (MemberCore mc,
-                       DeclSpace ds, Report Report)
+               internal void GenerateDocumentationForMember (MemberCore mc)
                {
-                       if (mc.DocComment != null) {
-                               string name = mc.GetDocCommentName (ds);
-
-                               XmlNode n = GetDocCommentNode (mc, name, Report);
-
-                               XmlElement el = n as XmlElement;
-                               if (el != null) {
-                                       mc.OnGenerateDocComment (el);
-
-                                       // FIXME: it could be done with XmlReader
-                                       XmlNodeList nl = n.SelectNodes (".//include");
-                                       if (nl.Count > 0) {
-                                               // It could result in current node removal, so prepare another list to iterate.
-                                               var al = new List<XmlNode> (nl.Count);
-                                               foreach (XmlNode inc in nl)
-                                                       al.Add (inc);
-                                               foreach (XmlElement inc in al)
-                                                       if (!HandleInclude (mc, inc, Report))
-                                                               inc.ParentNode.RemoveChild (inc);
-                                       }
+                       string name = mc.DocCommentHeader + mc.GetSignatureForDocumentation ();
 
-                                       // FIXME: it could be done with XmlReader
-                                       DeclSpace ds_target = mc as DeclSpace;
-                                       if (ds_target == null)
-                                               ds_target = ds;
-
-                                       foreach (XmlElement see in n.SelectNodes (".//see"))
-                                               HandleSee (mc, ds_target, see, Report);
-                                       foreach (XmlElement seealso in n.SelectNodes (".//seealso"))
-                                               HandleSeeAlso (mc, ds_target, seealso ,Report);
-                                       foreach (XmlElement see in n.SelectNodes (".//exception"))
-                                               HandleException (mc, ds_target, see, Report);
+                       XmlNode n = GetDocCommentNode (mc, name);
+
+                       XmlElement el = n as XmlElement;
+                       if (el != null) {
+                               var pm = mc as IParametersMember;
+                               if (pm != null) {
+                                       CheckParametersComments (mc, pm, el);
                                }
 
-                               n.WriteTo (mc.Compiler.Settings.Documentation.XmlCommentOutput);
-                       }
-                       else if (mc.IsExposedFromAssembly ()) {
-                               Constructor c = mc as Constructor;
-                               if (c == null || !c.IsDefault ())
-                                       Report.Warning (1591, 4, mc.Location,
-                                               "Missing XML comment for publicly visible type or member `{0}'", mc.GetSignatureForError ());
+                               // FIXME: it could be done with XmlReader
+                               XmlNodeList nl = n.SelectNodes (".//include");
+                               if (nl.Count > 0) {
+                                       // It could result in current node removal, so prepare another list to iterate.
+                                       var al = new List<XmlNode> (nl.Count);
+                                       foreach (XmlNode inc in nl)
+                                               al.Add (inc);
+                                       foreach (XmlElement inc in al)
+                                               if (!HandleInclude (mc, inc))
+                                                       inc.ParentNode.RemoveChild (inc);
+                               }
+
+                               // FIXME: it could be done with XmlReader
+                               var ds_target = mc as TypeContainer;
+                               if (ds_target == null)
+                                       ds_target = mc.Parent;
+
+                               foreach (XmlElement see in n.SelectNodes (".//see"))
+                                       HandleSee (mc, ds_target, see);
+                               foreach (XmlElement seealso in n.SelectNodes (".//seealso"))
+                                       HandleSeeAlso (mc, ds_target, seealso);
+                               foreach (XmlElement see in n.SelectNodes (".//exception"))
+                                       HandleException (mc, ds_target, see);
+                               foreach (XmlElement node in n.SelectNodes (".//typeparam"))
+                                       HandleTypeParam (mc, node);
+                               foreach (XmlElement node in n.SelectNodes (".//typeparamref"))
+                                       HandleTypeParamRef (mc, node);
                        }
+
+                       n.WriteTo (XmlCommentOutput);
                }
 
                //
                // Processes "include" element. Check included file and
                // embed the document content inside this documentation node.
                //
-               private static bool HandleInclude (MemberCore mc, XmlElement el, Report Report)
+               bool HandleInclude (MemberCore mc, XmlElement el)
                {
                        bool keep_include_node = false;
                        string file = el.GetAttribute ("file");
@@ -188,11 +185,11 @@ namespace Mono.CSharp {
                        }
                        else {
                                XmlDocument doc;
-                               if (!mc.Compiler.Settings.Documentation.StoredDocuments.TryGetValue (file, out doc)) {
+                               if (!StoredDocuments.TryGetValue (file, out doc)) {
                                        try {
                                                doc = new XmlDocument ();
                                                doc.Load (file);
-                                               mc.Compiler.Settings.Documentation.StoredDocuments.Add (file, doc);
+                                               StoredDocuments.Add (file, doc);
                                        } catch (Exception) {
                                                el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (String.Format (" Badly formed XML in at comment file `{0}': cannot be included ", file)), el);
                                                Report.Warning (1592, 1, mc.Location, "Badly formed XML in included comments file -- `{0}'", file);
@@ -220,464 +217,298 @@ namespace Mono.CSharp {
                //
                // Handles <see> elements.
                //
-               private static void HandleSee (MemberCore mc,
-                       DeclSpace ds, XmlElement see, Report r)
+               void HandleSee (MemberCore mc, TypeContainer ds, XmlElement see)
                {
-                       HandleXrefCommon (mc, ds, see, r);
+                       HandleXrefCommon (mc, ds, see);
                }
 
                //
                // Handles <seealso> elements.
                //
-               private static void HandleSeeAlso (MemberCore mc,
-                       DeclSpace ds, XmlElement seealso, Report r)
+               void HandleSeeAlso (MemberCore mc, TypeContainer ds, XmlElement seealso)
                {
-                       HandleXrefCommon (mc, ds, seealso, r);
+                       HandleXrefCommon (mc, ds, seealso);
                }
 
                //
                // Handles <exception> elements.
                //
-               private static void HandleException (MemberCore mc,
-                       DeclSpace ds, XmlElement seealso, Report r)
+               void HandleException (MemberCore mc, TypeContainer ds, XmlElement seealso)
                {
-                       HandleXrefCommon (mc, ds, seealso, r);
+                       HandleXrefCommon (mc, ds, seealso);
                }
 
-               static readonly char [] wsChars =
-                       new char [] {' ', '\t', '\n', '\r'};
-
                //
-               // returns a full runtime type name from a name which might
-               // be C# specific type name.
+               // Handles <typeparam /> node
                //
-               private static TypeSpec FindDocumentedType (MemberCore mc, string name, DeclSpace ds, string cref, Report r)
-               {
-                       bool is_array = false;
-                       string identifier = name;
-                       if (name [name.Length - 1] == ']') {
-                               string tmp = name.Substring (0, name.Length - 1).Trim (wsChars);
-                               if (tmp [tmp.Length - 1] == '[') {
-                                       identifier = tmp.Substring (0, tmp.Length - 1).Trim (wsChars);
-                                       is_array = true;
-                               }
-                       }
-                       TypeSpec t = FindDocumentedTypeNonArray (mc, identifier, ds, cref, r);
-                       if (t != null && is_array)
-                               t = ArrayContainer.MakeType (mc.Module, t);
-                       return t;
-               }
-
-               private static TypeSpec FindDocumentedTypeNonArray (MemberCore mc, 
-                       string identifier, DeclSpace ds, string cref, Report r)
+               void HandleTypeParam (MemberCore mc, XmlElement node)
                {
-                       var types = mc.Module.Compiler.BuiltinTypes;
-                       switch (identifier) {
-                       case "int":
-                               return types.Int;
-                       case "uint":
-                               return types.UInt;
-                       case "short":
-                               return types.Short;
-                       case "ushort":
-                               return types.UShort;
-                       case "long":
-                               return types.Long;
-                       case "ulong":
-                               return types.ULong;
-                       case "float":
-                               return types.Float;
-                       case "double":
-                               return types.Double;
-                       case "char":
-                               return types.Char;
-                       case "decimal":
-                               return types.Decimal;
-                       case "byte":
-                               return types.Byte;
-                       case "sbyte":
-                               return types.SByte;
-                       case "object":
-                               return types.Object;
-                       case "bool":
-                               return types.Bool;
-                       case "string":
-                               return types.String;
-                       case "void":
-                               return types.Void;
-                       }
-                       FullNamedExpression e = ds.LookupNamespaceOrType (identifier, 0, mc.Location, false);
-                       if (e != null) {
-                               if (!(e is TypeExpr))
-                                       return null;
-                               return e.Type;
-                       }
-                       int index = identifier.LastIndexOf ('.');
-                       if (index < 0)
-                               return null;
+                       if (!node.HasAttribute ("name"))
+                               return;
 
-                       var nsName = identifier.Substring (0, index);
-                       var typeName = identifier.Substring (index + 1);
-                       Namespace ns = ds.NamespaceEntry.NS.GetNamespace (nsName, false);
-                       ns = ns ?? mc.Module.GlobalRootNamespace.GetNamespace(nsName, false);
-                       if (ns != null) {
-                               var te = ns.LookupType(mc, typeName, 0, true, mc.Location);
-                               if(te != null)
-                                       return te.Type;
+                       string tp_name = node.GetAttribute ("name");
+                       if (mc.CurrentTypeParameters != null) {
+                               if (mc.CurrentTypeParameters.Find (tp_name) != null)
+                                       return;
                        }
-
-                       int warn;
-                       TypeSpec parent = FindDocumentedType (mc, identifier.Substring (0, index), ds, cref, r);
-                       if (parent == null)
-                               return null;
-                       // no need to detect warning 419 here
-                       var ts = FindDocumentedMember (mc, parent,
-                               identifier.Substring (index + 1),
-                               null, ds, out warn, cref, false, null, r) as TypeSpec;
-                       if (ts != null)
-                               return ts;
-                       return null;
+                       
+                       // TODO: CS1710, CS1712
+                       
+                       mc.Compiler.Report.Warning (1711, 2, mc.Location,
+                               "XML comment on `{0}' has a typeparam name `{1}' but there is no type parameter by that name",
+                               mc.GetSignatureForError (), tp_name);
                }
 
                //
-               // Returns a MemberInfo that is referenced in XML documentation
-               // (by "see" or "seealso" elements).
+               // Handles <typeparamref /> node
                //
-               private static MemberSpec FindDocumentedMember (MemberCore mc,
-                       TypeSpec type, string member_name, AParametersCollection param_list, 
-                       DeclSpace ds, out int warning_type, string cref,
-                       bool warn419, string name_for_error, Report r)
+               void HandleTypeParamRef (MemberCore mc, XmlElement node)
                {
-//                     for (; type != null; type = type.DeclaringType) {
-                               var mi = FindDocumentedMemberNoNest (
-                                       mc, type, member_name, param_list, ds,
-                                       out warning_type, cref, warn419,
-                                       name_for_error, r);
-                               if (mi != null)
-                                       return mi; // new FoundMember (type, mi);
-//                     }
-                       warning_type = 0;
-                       return null;
-               }
+                       if (!node.HasAttribute ("name"))
+                               return;
 
-               private static MemberSpec FindDocumentedMemberNoNest (
-                       MemberCore mc, TypeSpec type, string member_name,
-                       AParametersCollection param_list, DeclSpace ds, out int warning_type, 
-                       string cref, bool warn419, string name_for_error, Report Report)
-               {
-                       warning_type = 0;
-//                     var filter = new MemberFilter (member_name, 0, MemberKind.All, param_list, null);
-                       IList<MemberSpec> found = null;
-                       while (type != null && found == null) {
-                               found = MemberCache.FindMembers (type, member_name, false);
-                               type = type.DeclaringType;
-                       }
+                       string tp_name = node.GetAttribute ("name");
+                       var member = mc;
+                       do {
+                               if (member.CurrentTypeParameters != null) {
+                                       if (member.CurrentTypeParameters.Find (tp_name) != null)
+                                               return;
+                               }
 
-                       if (found == null)
-                               return null;
+                               member = member.Parent;
+                       } while (member != null);
 
-                       if (warn419 && found.Count > 1) {
-                               Report419 (mc, name_for_error, found.ToArray (), Report);
-                       }
+                       mc.Compiler.Report.Warning (1735, 2, mc.Location,
+                               "XML comment on `{0}' has a typeparamref name `{1}' that could not be resolved",
+                               mc.GetSignatureForError (), tp_name);
+               }
 
-                       return found [0];
-
-/*
-                       if (param_list == null) {
-                               // search for fields/events etc.
-                               mis = TypeManager.MemberLookup (type, null,
-                                       type, MemberKind.All,
-                                       BindingRestriction.None,
-                                       member_name, null);
-                               mis = FilterOverridenMembersOut (mis);
-                               if (mis == null || mis.Length == 0)
-                                       return null;
-                               if (warn419 && IsAmbiguous (mis))
-                                       Report419 (mc, name_for_error, mis, Report);
-                               return mis [0];
-                       }
+               FullNamedExpression ResolveMemberName (IMemberContext context, MemberName mn)
+               {
+                       if (mn.Left == null)
+                               return context.LookupNamespaceOrType (mn.Name, mn.Arity, LookupMode.Probing, Location.Null);
 
-                       MethodSignature msig = new MethodSignature (member_name, null, param_list);
-                       mis = FindMethodBase (type, 
-                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
-                               msig);
+                       var left = ResolveMemberName (context, mn.Left);
+                       var ns = left as Namespace;
+                       if (ns != null)
+                               return ns.LookupTypeOrNamespace (context, mn.Name, mn.Arity, LookupMode.Probing, Location.Null);
 
-                       if (warn419 && mis.Length > 0) {
-                               if (IsAmbiguous (mis))
-                                       Report419 (mc, name_for_error, mis, Report);
-                               return mis [0];
-                       }
+                       TypeExpr texpr = left as TypeExpr;
+                       if (texpr != null) {
+                               var found = MemberCache.FindNestedType (texpr.Type, ParsedName.Name, ParsedName.Arity);
+                               if (found != null)
+                                       return new TypeExpression (found, Location.Null);
 
-                       // search for operators (whose parameters exactly
-                       // matches with the list) and possibly report CS1581.
-                       string oper = null;
-                       string return_type_name = null;
-                       if (member_name.StartsWith ("implicit operator ")) {
-                               Operator.GetMetadataName (Operator.OpType.Implicit);
-                               return_type_name = member_name.Substring (18).Trim (wsChars);
-                       }
-                       else if (member_name.StartsWith ("explicit operator ")) {
-                               oper = Operator.GetMetadataName (Operator.OpType.Explicit);
-                               return_type_name = member_name.Substring (18).Trim (wsChars);
-                       }
-                       else if (member_name.StartsWith ("operator ")) {
-                               oper = member_name.Substring (9).Trim (wsChars);
-                               switch (oper) {
-                               // either unary or binary
-                               case "+":
-                                       oper = param_list.Length == 2 ?
-                                               Operator.GetMetadataName (Operator.OpType.Addition) :
-                                               Operator.GetMetadataName (Operator.OpType.UnaryPlus);
-                                       break;
-                               case "-":
-                                       oper = param_list.Length == 2 ?
-                                               Operator.GetMetadataName (Operator.OpType.Subtraction) :
-                                               Operator.GetMetadataName (Operator.OpType.UnaryNegation);
-                                       break;
-                               default:
-                                       oper = Operator.GetMetadataName (oper);
-                                       if (oper != null)
-                                               break;
-
-                                       warning_type = 1584;
-                                       Report.Warning (1020, 1, mc.Location, "Overloadable {0} operator is expected", param_list.Length == 2 ? "binary" : "unary");
-                                       Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
-                                               mc.GetSignatureForError (), cref);
-                                       return null;
-                               }
-                       }
-                       // here we still don't consider return type (to
-                       // detect CS1581 or CS1002+CS1584).
-                       msig = new MethodSignature (oper, null, param_list);
-
-                       mis = FindMethodBase (type, 
-                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
-                               msig);
-                       if (mis.Length == 0)
-                               return null; // CS1574
-                       var mi = mis [0];
-                       TypeSpec expected = mi is MethodSpec ?
-                               ((MethodSpec) mi).ReturnType :
-                               mi is PropertySpec ?
-                               ((PropertySpec) mi).PropertyType :
-                               null;
-                       if (return_type_name != null) {
-                               TypeSpec returnType = FindDocumentedType (mc, return_type_name, ds, cref, Report);
-                               if (returnType == null || returnType != expected) {
-                                       warning_type = 1581;
-                                       Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref);
-                                       return null;
-                               }
+                               return null;
                        }
-                       return mis [0];
-*/ 
+
+                       return left;
                }
 
                //
-               // Processes "see" or "seealso" elements.
-               // Checks cref attribute.
+               // Processes "see" or "seealso" elements from cref attribute.
                //
-               private static void HandleXrefCommon (MemberCore mc,
-                       DeclSpace ds, XmlElement xref, Report Report)
+               void HandleXrefCommon (MemberCore mc, TypeContainer ds, XmlElement xref)
                {
-                       string cref = xref.GetAttribute ("cref").Trim (wsChars);
+                       string cref = xref.GetAttribute ("cref");
                        // when, XmlReader, "if (cref == null)"
                        if (!xref.HasAttribute ("cref"))
                                return;
-                       if (cref.Length == 0)
-                               Report.Warning (1001, 1, mc.Location, "Identifier expected");
-                               // ... and continue until CS1584.
-
-                       string signature; // "x:" are stripped
-                       string name; // method invokation "(...)" are removed
-                       string parameters; // method parameter list
-
-                       // When it found '?:' ('T:' 'M:' 'F:' 'P:' 'E:' etc.),
-                       // MS ignores not only its member kind, but also
-                       // the entire syntax correctness. Nor it also does
-                       // type fullname resolution i.e. "T:List(int)" is kept
-                       // as T:List(int), not
-                       // T:System.Collections.Generic.List&lt;System.Int32&gt;
+
+                       // Nothing to be resolved the reference is marked explicitly
                        if (cref.Length > 2 && cref [1] == ':')
                                return;
-                       else
-                               signature = cref;
-
-                       // Also note that without "T:" any generic type 
-                       // indication fails.
-
-                       int parens_pos = signature.IndexOf ('(');
-                       int brace_pos = parens_pos >= 0 ? -1 :
-                               signature.IndexOf ('[');
-                       if (parens_pos > 0 && signature [signature.Length - 1] == ')') {
-                               name = signature.Substring (0, parens_pos).Trim (wsChars);
-                               parameters = signature.Substring (parens_pos + 1, signature.Length - parens_pos - 2).Trim (wsChars);
-                       }
-                       else if (brace_pos > 0 && signature [signature.Length - 1] == ']') {
-                               name = signature.Substring (0, brace_pos).Trim (wsChars);
-                               parameters = signature.Substring (brace_pos + 1, signature.Length - brace_pos - 2).Trim (wsChars);
-                       }
-                       else {
-                               name = signature;
-                               parameters = null;
-                       }
-                       Normalize (mc, ref name, Report);
-
-                       string identifier = GetBodyIdentifierFromName (name);
-
-                       // Check if identifier is valid.
-                       // This check is not necessary to mark as error, but
-                       // csc specially reports CS1584 for wrong identifiers.
-                       string [] name_elems = identifier.Split ('.');
-                       for (int i = 0; i < name_elems.Length; i++) {
-                               string nameElem = GetBodyIdentifierFromName (name_elems [i]);
-                               if (i > 0)
-                                       Normalize (mc, ref nameElem, Report);
-                               if (!Tokenizer.IsValidIdentifier (nameElem)
-                                       && nameElem.IndexOf ("operator") < 0) {
-                                       Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
-                                               mc.GetSignatureForError (), cref);
-                                       xref.SetAttribute ("cref", "!:" + signature);
-                                       return;
-                               }
-                       }
 
-                       // check if parameters are valid
-                       AParametersCollection parameter_types;
-                       if (parameters == null)
-                               parameter_types = null;
-                       else if (parameters.Length == 0)
-                               parameter_types = ParametersCompiled.EmptyReadOnlyParameters;
-                       else {
-                               string [] param_list = parameters.Split (',');
-                               var plist = new List<TypeSpec> ();
-                               for (int i = 0; i < param_list.Length; i++) {
-                                       string param_type_name = param_list [i].Trim (wsChars);
-                                       Normalize (mc, ref param_type_name, Report);
-                                       TypeSpec param_type = FindDocumentedType (mc, param_type_name, ds, cref, Report);
-                                       if (param_type == null) {
-                                               Report.Warning (1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'",
-                                                       (i + 1).ToString (), cref);
-                                               return;
-                                       }
-                                       plist.Add (param_type);
-                               }
-
-                               parameter_types = ParametersCompiled.CreateFullyResolved (plist.ToArray ());
+                       // Additional symbols for < and > are allowed for easier XML typing
+                       cref = cref.Replace ('{', '<').Replace ('}', '>');
+
+                       var encoding = module.Compiler.Settings.Encoding;
+                       var s = new MemoryStream (encoding.GetBytes (cref));
+                       SeekableStreamReader seekable = new SeekableStreamReader (s, encoding);
+
+                       var source_file = new CompilationSourceFile (doc_module);
+                       var report = new Report (doc_module.Compiler, new NullReportPrinter ());
+
+                       var parser = new CSharpParser (seekable, source_file, report);
+                       ParsedParameters = null;
+                       ParsedName = null;
+                       ParsedBuiltinType = null;
+                       ParsedOperator = null;
+                       parser.Lexer.putback_char = Tokenizer.DocumentationXref;
+                       parser.Lexer.parsing_generic_declaration_doc = true;
+                       parser.parse ();
+                       if (report.Errors > 0) {
+                               Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
+                                       mc.GetSignatureForError (), cref);
+
+                               xref.SetAttribute ("cref", "!:" + cref);
+                               return;
                        }
 
-                       TypeSpec type = FindDocumentedType (mc, name, ds, cref, Report);
-                       if (type != null
-                               // delegate must not be referenced with args
-                               && (!type.IsDelegate
-                               || parameter_types == null)) {
-                               string result = GetSignatureForDoc (type)
-                                       + (brace_pos < 0 ? String.Empty : signature.Substring (brace_pos));
-                               xref.SetAttribute ("cref", "T:" + result);
-                               return; // a type
-                       }
+                       MemberSpec member;
+                       string prefix = null;
+                       FullNamedExpression fne = null;
 
-                       int period = name.LastIndexOf ('.');
-                       if (period > 0) {
-                               string typeName = name.Substring (0, period);
-                               string member_name = name.Substring (period + 1);
-                               string lookup_name = member_name == "this" ? MemberCache.IndexerNameAlias : member_name;
-                               Normalize (mc, ref lookup_name, Report);
-                               Normalize (mc, ref member_name, Report);
-                               type = FindDocumentedType (mc, typeName, ds, cref, Report);
-                               int warn_result;
-                               if (type != null) {
-                                       var mi = FindDocumentedMember (mc, type, lookup_name, parameter_types, ds, out warn_result, cref, true, name, Report);
-                                       if (warn_result > 0)
-                                               return;
-                                       if (mi != null) {
-                                               // we cannot use 'type' directly
-                                               // to get its name, since mi
-                                               // could be from DeclaringType
-                                               // for nested types.
-                                               xref.SetAttribute ("cref", GetMemberDocHead (mi) + GetSignatureForDoc (mi.DeclaringType) + "." + member_name + GetParametersFormatted (mi));
-                                               return; // a member of a type
+                       //
+                       // Try built-in type first because we are using ParsedName as identifier of
+                       // member names on built-in types
+                       //
+                       if (ParsedBuiltinType != null && (ParsedParameters == null || ParsedName != null)) {
+                               member = ParsedBuiltinType.Type;
+                       } else {
+                               member = null;
+                       }
+
+                       if (ParsedName != null || ParsedOperator.HasValue) {
+                               TypeSpec type = null;
+                               string member_name = null;
+
+                               if (member == null) {
+                                       if (ParsedOperator.HasValue) {
+                                               type = mc.CurrentType;
+                                       } else if (ParsedName.Left != null) {
+                                               fne = ResolveMemberName (mc, ParsedName.Left);
+                                               if (fne != null) {
+                                                       var ns = fne as Namespace;
+                                                       if (ns != null) {
+                                                               fne = ns.LookupTypeOrNamespace (mc, ParsedName.Name, ParsedName.Arity, LookupMode.Probing, Location.Null);
+                                                               if (fne != null) {
+                                                                       member = fne.Type;
+                                                               }
+                                                       } else {
+                                                               type = fne.Type;
+                                                       }
+                                               }
+                                       } else {
+                                               fne = ResolveMemberName (mc, ParsedName);
+                                               if (fne == null) {
+                                                       type = mc.CurrentType;
+                                               } else if (ParsedParameters == null) {
+                                                       member = fne.Type;
+                                               } else if (fne.Type.MemberDefinition == mc.CurrentType.MemberDefinition) {
+                                                       member_name = Constructor.ConstructorName;
+                                                       type = fne.Type;
+                                               }
                                        }
+                               } else {
+                                       type = (TypeSpec) member;
+                                       member = null;
                                }
-                       } else {
-                               int warn_result;
-                               var mi = FindDocumentedMember (mc, ds.PartialContainer.Definition, name, parameter_types, ds, out warn_result, cref, true, name, Report);
 
-                               if (warn_result > 0)
-                                       return;
-                               if (mi != null) {
-                                       // we cannot use 'type' directly
-                                       // to get its name, since mi
-                                       // could be from DeclaringType
-                                       // for nested types.
-                                       xref.SetAttribute ("cref", GetMemberDocHead (mi) + GetSignatureForDoc (mi.DeclaringType) + "." + name + GetParametersFormatted (mi));
-                                       return; // local member name
+                               if (ParsedParameters != null) {
+                                       var old_printer = mc.Module.Compiler.Report.SetPrinter (new NullReportPrinter ());
+                                       foreach (var pp in ParsedParameters) {
+                                               pp.Resolve (mc);
+                                       }
+                                       mc.Module.Compiler.Report.SetPrinter (old_printer);
                                }
-                       }
 
-                       // It still might be part of namespace name.
-                       Namespace ns = ds.NamespaceEntry.NS.GetNamespace (name, false);
-                       if (ns != null) {
-                               xref.SetAttribute ("cref", "N:" + ns.GetSignatureForError ());
-                               return; // a namespace
-                       }
-                       if (mc.Module.GlobalRootNamespace.IsNamespace (name)) {
-                               xref.SetAttribute ("cref", "N:" + name);
-                               return; // a namespace
-                       }
-
-                       Report.Warning (1574, 1, mc.Location, "XML comment on `{0}' has cref attribute `{1}' that could not be resolved",
-                               mc.GetSignatureForError (), cref);
+                               if (type != null) {
+                                       if (member_name == null)
+                                               member_name = ParsedOperator.HasValue ?
+                                                       Operator.GetMetadataName (ParsedOperator.Value) : ParsedName.Name;
+
+                                       int parsed_param_count;
+                                       if (ParsedOperator == Operator.OpType.Explicit || ParsedOperator == Operator.OpType.Implicit) {
+                                               parsed_param_count = ParsedParameters.Count - 1;
+                                       } else if (ParsedParameters != null) {
+                                               parsed_param_count = ParsedParameters.Count;
+                                       } else {
+                                               parsed_param_count = 0;
+                                       }
 
-                       xref.SetAttribute ("cref", "!:" + name);
-               }
+                                       int parameters_match = -1;
+                                       do {
+                                               var members = MemberCache.FindMembers (type, member_name, true);
+                                               if (members != null) {
+                                                       foreach (var m in members) {
+                                                               if (ParsedName != null && m.Arity != ParsedName.Arity)
+                                                                       continue;
+
+                                                               if (ParsedParameters != null) {
+                                                                       IParametersMember pm = m as IParametersMember;
+                                                                       if (pm == null)
+                                                                               continue;
+
+                                                                       if (m.Kind == MemberKind.Operator && !ParsedOperator.HasValue)
+                                                                               continue;
+
+                                                                       int i;
+                                                                       for (i = 0; i < parsed_param_count; ++i) {
+                                                                               var pparam = ParsedParameters[i];
+
+                                                                               if (i >= pm.Parameters.Count || pparam == null ||
+                                                                                       pparam.TypeSpec != pm.Parameters.Types[i] ||
+                                                                                       (pparam.Modifier & Parameter.Modifier.SignatureMask) != (pm.Parameters.FixedParameters[i].ModFlags & Parameter.Modifier.SignatureMask)) {
+
+                                                                                       if (i > parameters_match) {
+                                                                                               parameters_match = i;
+                                                                                       }
+
+                                                                                       i = -1;
+                                                                                       break;
+                                                                               }
+                                                                       }
+
+                                                                       if (i < 0)
+                                                                               continue;
+
+                                                                       if (ParsedOperator == Operator.OpType.Explicit || ParsedOperator == Operator.OpType.Implicit) {
+                                                                               if (pm.MemberType != ParsedParameters[parsed_param_count].TypeSpec) {
+                                                                                       parameters_match = parsed_param_count + 1;
+                                                                                       continue;
+                                                                               }
+                                                                       } else {
+                                                                               if (parsed_param_count != pm.Parameters.Count)
+                                                                                       continue;
+                                                                       }
+                                                               }
+
+                                                               if (member != null) {
+                                                                       Report.Warning (419, 3, mc.Location,
+                                                                               "Ambiguous reference in cref attribute `{0}'. Assuming `{1}' but other overloads including `{2}' have also matched",
+                                                                               cref, member.GetSignatureForError (), m.GetSignatureForError ());
+
+                                                                       break;
+                                                               }
+
+                                                               member = m;
+                                                       }
+                                               }
 
-               static string GetParametersFormatted (MemberSpec mi)
-               {
-                       var pm = mi as IParametersMember;
-                       if (pm == null || pm.Parameters.IsEmpty)
-                               return string.Empty;
-
-                       AParametersCollection parameters = pm.Parameters;
-/*
-                       if (parameters == null || parameters.Count == 0)
-                               return String.Empty;
-*/
-                       StringBuilder sb = new StringBuilder ();
-                       sb.Append ('(');
-                       for (int i = 0; i < parameters.Count; i++) {
-//                             if (is_setter && i + 1 == parameters.Count)
-//                                     break; // skip "value".
-                               if (i > 0)
-                                       sb.Append (',');
-                               TypeSpec t = parameters.Types [i];
-                               sb.Append (GetSignatureForDoc (t));
-                       }
-                       sb.Append (')');
-                       return sb.ToString ();
-               }
+                                               // Continue with parent type for nested types
+                                               if (member == null) {
+                                                       type = type.DeclaringType;
+                                               } else {
+                                                       type = null;
+                                               }
+                                       } while (type != null);
 
-               static string GetBodyIdentifierFromName (string name)
-               {
-                       string identifier = name;
+                                       if (member == null && parameters_match >= 0) {
+                                               for (int i = parameters_match; i < parsed_param_count; ++i) {
+                                                       Report.Warning (1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'",
+                                                                       (i + 1).ToString (), cref);
+                                               }
 
-                       if (name.Length > 0 && name [name.Length - 1] == ']') {
-                               string tmp = name.Substring (0, name.Length - 1).Trim (wsChars);
-                               int last = tmp.LastIndexOf ('[');
-                               if (last > 0)
-                                       identifier = tmp.Substring (0, last).Trim (wsChars);
+                                               if (parameters_match == parsed_param_count + 1) {
+                                                       Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref);
+                                               }
+                                       }
+                               }
                        }
 
-                       return identifier;
-               }
+                       if (member == null) {
+                               Report.Warning (1574, 1, mc.Location, "XML comment on `{0}' has cref attribute `{1}' that could not be resolved",
+                                       mc.GetSignatureForError (), cref);
+                               cref = "!:" + cref;
+                       } else if (member == InternalType.Namespace) {
+                               cref = "N:" + fne.GetSignatureForError ();
+                       } else {
+                               prefix = GetMemberDocHead (member);
+                               cref = prefix + member.GetSignatureForDocumentation ();
+                       }
 
-               static void Report419 (MemberCore mc, string member_name, MemberSpec [] mis, Report Report)
-               {
-                       Report.Warning (419, 3, mc.Location, 
-                               "Ambiguous reference in cref attribute `{0}'. Assuming `{1}' but other overloads including `{2}' have also matched",
-                               member_name,
-                               TypeManager.GetFullNameSignature (mis [0]),
-                               TypeManager.GetFullNameSignature (mis [1]));
+                       xref.SetAttribute ("cref", cref);
                }
 
                //
@@ -697,97 +528,7 @@ namespace Mono.CSharp {
                        if (type is TypeSpec)
                                return "T:";
 
-                       return "!:";
-               }
-
-               // MethodCore
-
-               //
-               // Returns a string that represents the signature for this 
-               // member which should be used in XML documentation.
-               //
-               public static string GetMethodDocCommentName (MemberCore mc, ParametersCompiled parameters, DeclSpace ds)
-               {
-                       IParameterData [] plist = parameters.FixedParameters;
-                       string paramSpec = String.Empty;
-                       if (plist != null) {
-                               StringBuilder psb = new StringBuilder ();
-                               int i = 0;
-                               foreach (Parameter p in plist) {
-                                       psb.Append (psb.Length != 0 ? "," : "(");
-                                       psb.Append (GetSignatureForDoc (parameters.Types [i++]));
-                                       if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0)
-                                               psb.Append ('@');
-                               }
-                               paramSpec = psb.ToString ();
-                       }
-
-                       if (paramSpec.Length > 0)
-                               paramSpec += ")";
-
-                       string name = mc.Name;
-                       if (mc is Constructor)
-                               name = "#ctor";
-                       else if (mc is InterfaceMemberBase) {
-                               var imb = (InterfaceMemberBase) mc;
-                               name = imb.GetFullName (imb.ShortName);
-                       }
-                       name = name.Replace ('.', '#');
-
-                       if (mc.MemberName.TypeArguments != null && mc.MemberName.TypeArguments.Count > 0)
-                               name += "``" + mc.MemberName.CountTypeArguments;
-
-                       string suffix = String.Empty;
-                       Operator op = mc as Operator;
-                       if (op != null) {
-                               switch (op.OperatorType) {
-                               case Operator.OpType.Implicit:
-                               case Operator.OpType.Explicit:
-                                       suffix = "~" + GetSignatureForDoc (op.ReturnType);
-                                       break;
-                               }
-                       }
-                       return String.Concat (mc.DocCommentHeader, ds.Name, ".", name, paramSpec, suffix);
-               }
-
-               static string GetSignatureForDoc (TypeSpec type)
-               {
-                       var tp = type as TypeParameterSpec;
-                       if (tp != null) {
-                               int c = 0;
-                               type = type.DeclaringType;
-                               while (type != null && type.DeclaringType != null) {
-                                       type = type.DeclaringType;
-                                       c += type.MemberDefinition.TypeParametersCount;
-                               }
-                               var prefix = tp.IsMethodOwned ? "``" : "`";
-                               return prefix + (c + tp.DeclaredPosition);
-                       }
-
-                       var pp = type as PointerContainer;
-                       if (pp != null)
-                               return GetSignatureForDoc (pp.Element) + "*";
-
-                       ArrayContainer ap = type as ArrayContainer;
-                       if (ap != null)
-                               return GetSignatureForDoc (ap.Element) +
-                                       ArrayContainer.GetPostfixSignature (ap.Rank);
-
-                       if (TypeManager.IsGenericType (type)) {
-                               string g = type.MemberDefinition.Namespace;
-                               if (g != null && g.Length > 0)
-                                       g += '.';
-                               int idx = type.Name.LastIndexOf ('`');
-                               g += (idx < 0 ? type.Name : type.Name.Substring (0, idx)) + '{';
-                               int argpos = 0;
-                               foreach (TypeSpec t in TypeManager.GetTypeArguments (type))
-                                       g += (argpos++ > 0 ? "," : String.Empty) + GetSignatureForDoc (t);
-                               g += '}';
-                               return g;
-                       }
-
-                       string name = type.GetMetaInfo ().FullName != null ? type.GetMetaInfo ().FullName : type.Name;
-                       return name.Replace ("+", ".").Replace ('&', '@');
+                       throw new NotImplementedException (type.GetType ().ToString ());
                }
 
                //
@@ -797,139 +538,106 @@ namespace Mono.CSharp {
                // FIXME: with a few effort, it could be done with XmlReader,
                // that means removal of DOM use.
                //
-               internal static void OnMethodGenerateDocComment (
-                       MethodCore mc, XmlElement el, Report Report)
+               void CheckParametersComments (MemberCore member, IParametersMember paramMember, XmlElement el)
                {
-                       var paramTags = new Dictionary<string, string> ();
+                       HashSet<string> found_tags = null;
                        foreach (XmlElement pelem in el.SelectNodes ("param")) {
                                string xname = pelem.GetAttribute ("name");
                                if (xname.Length == 0)
                                        continue; // really? but MS looks doing so
-                               if (xname != "" && mc.ParameterInfo.GetParameterIndexByName (xname) < 0)
-                                       Report.Warning (1572, 2, mc.Location, "XML comment on `{0}' has a param tag for `{1}', but there is no parameter by that name",
-                                               mc.GetSignatureForError (), xname);
-                               else if (paramTags.ContainsKey (xname))
-                                       Report.Warning (1571, 2, mc.Location, "XML comment on `{0}' has a duplicate param tag for `{1}'",
-                                               mc.GetSignatureForError (), xname);
-                               paramTags [xname] = xname;
-                       }
-                       IParameterData [] plist = mc.ParameterInfo.FixedParameters;
-                       foreach (Parameter p in plist) {
-                               if (paramTags.Count > 0 && !paramTags.ContainsKey (p.Name))
-                                       Report.Warning (1573, 4, mc.Location, "Parameter `{0}' has no matching param tag in the XML comment for `{1}'",
-                                               p.Name, mc.GetSignatureForError ());
-                       }
-               }
-
-               private static void Normalize (MemberCore mc, ref string name, Report Report)
-               {
-                       if (name.Length > 0 && name [0] == '@')
-                               name = name.Substring (1);
-                       else if (name == "this")
-                               name = "Item";
-                       else if (Tokenizer.IsKeyword (name) && !IsTypeName (name))
-                               Report.Warning (1041, 1, mc.Location, "Identifier expected. `{0}' is a keyword", name);
-               }
 
-               private static bool IsTypeName (string name)
-               {
-                       switch (name) {
-                       case "bool":
-                       case "byte":
-                       case "char":
-                       case "decimal":
-                       case "double":
-                       case "float":
-                       case "int":
-                       case "long":
-                       case "object":
-                       case "sbyte":
-                       case "short":
-                       case "string":
-                       case "uint":
-                       case "ulong":
-                       case "ushort":
-                       case "void":
-                               return true;
-                       }
-                       return false;
-               }
-       }
-
-       //
-       // Implements XML documentation generation.
-       //
-       public class Documentation
-       {
-               public Documentation (string xml_output_filename)
-               {
-                       docfilename = xml_output_filename;
-                       XmlDocumentation = new XmlDocument ();
-                       XmlDocumentation.PreserveWhitespace = false;
-               }
+                               if (found_tags == null) {
+                                       found_tags = new HashSet<string> ();
+                               }
 
-               private string docfilename;
+                               if (xname != "" && paramMember.Parameters.GetParameterIndexByName (xname) < 0) {
+                                       Report.Warning (1572, 2, member.Location,
+                                               "XML comment on `{0}' has a param tag for `{1}', but there is no parameter by that name",
+                                               member.GetSignatureForError (), xname);
+                                       continue;
+                               }
 
-               //
-               // Used to create element which helps well-formedness checking.
-               //
-               public XmlDocument XmlDocumentation;
+                               if (found_tags.Contains (xname)) {
+                                       Report.Warning (1571, 2, member.Location,
+                                               "XML comment on `{0}' has a duplicate param tag for `{1}'",
+                                               member.GetSignatureForError (), xname);
+                                       continue;
+                               }
 
-               //
-               // The output for XML documentation.
-               //
-               public XmlWriter XmlCommentOutput;
+                               found_tags.Add (xname);
+                       }
 
-               //
-               // Stores XmlDocuments that are included in XML documentation.
-               // Keys are included filenames, values are XmlDocuments.
-               //
-               public Dictionary<string, XmlDocument> StoredDocuments = new Dictionary<string, XmlDocument> ();
+                       if (found_tags != null) {
+                               foreach (Parameter p in paramMember.Parameters.FixedParameters) {
+                                       if (!found_tags.Contains (p.Name) && !(p is ArglistParameter))
+                                               Report.Warning (1573, 4, member.Location,
+                                                       "Parameter `{0}' has no matching param tag in the XML comment for `{1}'",
+                                                       p.Name, member.GetSignatureForError ());
+                               }
+                       }
+               }
 
                //
                // Outputs XML documentation comment from tokenized comments.
                //
-               public bool OutputDocComment (string asmfilename, Report Report)
+               public bool OutputDocComment (string asmfilename, string xmlFileName)
                {
                        XmlTextWriter w = null;
                        try {
-                               w = new XmlTextWriter (docfilename, null);
+                               w = new XmlTextWriter (xmlFileName, null);
                                w.Indentation = 4;
                                w.Formatting = Formatting.Indented;
                                w.WriteStartDocument ();
                                w.WriteStartElement ("doc");
                                w.WriteStartElement ("assembly");
                                w.WriteStartElement ("name");
-                               w.WriteString (Path.ChangeExtension (asmfilename, null));
+                               w.WriteString (Path.GetFileNameWithoutExtension (asmfilename));
                                w.WriteEndElement (); // name
                                w.WriteEndElement (); // assembly
                                w.WriteStartElement ("members");
                                XmlCommentOutput = w;
-                               GenerateDocComment (Report);
+                               module.GenerateDocComment (this);
                                w.WriteFullEndElement (); // members
                                w.WriteEndElement ();
                                w.WriteWhitespace (Environment.NewLine);
                                w.WriteEndDocument ();
                                return true;
                        } catch (Exception ex) {
-                               Report.Error (1569, "Error generating XML documentation file `{0}' (`{1}')", docfilename, ex.Message);
+                               Report.Error (1569, "Error generating XML documentation file `{0}' (`{1}')", xmlFileName, ex.Message);
                                return false;
                        } finally {
                                if (w != null)
                                        w.Close ();
                        }
                }
+       }
 
-               //
-               // Fixes full type name of each documented types/members up.
-               //
-               public void GenerateDocComment (Report r)
+       class DocumentationParameter
+       {
+               public readonly Parameter.Modifier Modifier;
+               public FullNamedExpression Type;
+               TypeSpec type;
+
+               public DocumentationParameter (Parameter.Modifier modifier, FullNamedExpression type)
+                       : this (type)
                {
-                       TypeContainer root = RootContext.ToplevelTypes;
+                       this.Modifier = modifier;
+               }
 
-                       if (root.Types != null)
-                               foreach (TypeContainer tc in root.Types)
-                                       DocUtil.GenerateTypeDocComment (tc, null, r);
+               public DocumentationParameter (FullNamedExpression type)
+               {
+                       this.Type = type;
+               }
+
+               public TypeSpec TypeSpec {
+                       get {
+                               return type;
+                       }
+               }
+
+               public void Resolve (IMemberContext context)
+               {
+                       type = Type.ResolveAsType (context);
                }
        }
 }