⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doc.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
//// doc.cs: Support for XML documentation comment.//// Author://	Atsushi Enomoto <atsushi@ximian.com>//// Licensed under the terms of the GNU GPL//// (C) 2004 Novell, Inc.////#if ! BOOTSTRAP_WITH_OLDLIBusing System;using System.Collections;using System.Collections.Specialized;using System.IO;using System.Reflection;using System.Reflection.Emit;using System.Runtime.CompilerServices;using System.Runtime.InteropServices;using System.Security;using System.Security.Permissions;using System.Text;using System.Xml;using Mono.CompilerServices.SymbolWriter;namespace Mono.CSharp {	//	// Support class for XML documentation.	//	public class DocUtil	{		// TypeContainer		//		// Generates xml doc comments (if any), and if required,		// handle warning report.		//		internal static void GenerateTypeDocComment (TypeContainer t,			DeclSpace ds)		{			GenerateDocComment (t, ds);			if (t.DefaultStaticConstructor != null)				t.DefaultStaticConstructor.GenerateDocComment (t);			if (t.InstanceConstructors != null)				foreach (Constructor c in t.InstanceConstructors)					c.GenerateDocComment (t);			if (t.Types != null)				foreach (TypeContainer tc in t.Types)					tc.GenerateDocComment (t);			if (t.Parts != null) {				IDictionary comments = RootContext.Documentation.PartialComments;				foreach (ClassPart cp in t.Parts) {					if (cp.DocComment == null)						continue;					comments [cp] = cp;				}			}			if (t.Enums != null)				foreach (Enum en in t.Enums)					en.GenerateDocComment (t);			if (t.Constants != null)				foreach (Const c in t.Constants)					c.GenerateDocComment (t);			if (t.Fields != null)				foreach (Field f in t.Fields)					f.GenerateDocComment (t);			if (t.Events != null)				foreach (Event e in t.Events)					e.GenerateDocComment (t);			if (t.Indexers != null)				foreach (Indexer ix in t.Indexers)					ix.GenerateDocComment (t);			if (t.Properties != null)				foreach (Property p in t.Properties)					p.GenerateDocComment (t);			if (t.Methods != null)				foreach (Method m in t.Methods)					m.GenerateDocComment (t);			if (t.Operators != null)				foreach (Operator o in t.Operators)					o.GenerateDocComment (t);		}		// MemberCore		private static readonly string lineHead =			Environment.NewLine + "            ";		private static 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 = RootContext.Documentation.XmlDocumentation;			try {				XmlElement el = doc.CreateElement ("member");				el.SetAttribute ("name", name);				string normalized = mc.DocComment;				el.InnerXml = normalized;				// csc keeps lines as written in the sources				// and inserts formatting indentation (which 				// is different from XmlTextWriter.Formatting				// one), but when a start tag contains an 				// endline, it joins the next line. We don't				// have to follow such a hacky behavior.				string [] split =					normalized.Split ('\n');				int j = 0;				for (int i = 0; i < split.Length; i++) {					string s = split [i].TrimEnd ();					if (s.Length > 0)						split [j++] = s;				}				el.InnerXml = lineHead + String.Join (					lineHead, split, 0, j);				return el;			} catch (XmlException 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;			}		}		//		// Generates xml doc comments (if any), and if required,		// handle warning report.		//		internal static void GenerateDocComment (MemberCore mc,			DeclSpace ds)		{			if (mc.DocComment != null) {				string name = mc.GetDocCommentName (ds);				XmlNode n = GetDocCommentNode (mc, name);				XmlElement el = n as XmlElement;				if (el != null) {					mc.OnGenerateDocComment (ds, el);					// FIXME: it could be done with XmlReader					foreach (XmlElement inc in n.SelectNodes (".//include"))						HandleInclude (mc, inc);					// FIXME: it could be done with XmlReader					DeclSpace dsTarget = mc as DeclSpace;					if (dsTarget == null)						dsTarget = ds;					foreach (XmlElement see in n.SelectNodes (".//see"))						HandleSee (mc, dsTarget, see);					foreach (XmlElement seealso in n.SelectNodes (".//seealso"))						HandleSeeAlso (mc, dsTarget, seealso);					foreach (XmlElement see in n.SelectNodes (".//exception"))						HandleException (mc, dsTarget, see);				}				n.WriteTo (RootContext.Documentation.XmlCommentOutput);			}			else if (mc.IsExposedFromAssembly (ds)) {				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 ());			}		}		//		// Processes "include" element. Check included file and		// embed the document content inside this documentation node.		//		private static void HandleInclude (MemberCore mc, XmlElement el)		{			string file = el.GetAttribute ("file");			string path = el.GetAttribute ("path");			if (file == "") {				Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `file' attribute");				el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);			}			else if (path == "") {				Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `path' attribute");				el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);			}			else {				XmlDocument doc = RootContext.Documentation.StoredDocuments [file] as XmlDocument;				if (doc == null) {					try {						doc = new XmlDocument ();						doc.Load (file);						RootContext.Documentation.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);					}				}				bool keepIncludeNode = false;				if (doc != null) {					try {						XmlNodeList nl = doc.SelectNodes (path);						if (nl.Count == 0) {							el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" No matching elements were found for the include tag embedded here. "), el);												keepIncludeNode = true;						}						foreach (XmlNode n in nl)							el.ParentNode.InsertBefore (el.OwnerDocument.ImportNode (n, true), el);					} catch (Exception ex) {						el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Failed to insert some or all of included XML "), el);						Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}' ({2})", path, file, ex.Message);					}				}				if (!keepIncludeNode)					el.ParentNode.RemoveChild (el);			}		}		//		// Handles <see> elements.		//		private static void HandleSee (MemberCore mc,			DeclSpace ds, XmlElement see)		{			HandleXrefCommon (mc, ds, see);		}		//		// Handles <seealso> elements.		//		private static void HandleSeeAlso (MemberCore mc,			DeclSpace ds, XmlElement seealso)		{			HandleXrefCommon (mc, ds, seealso);		}		//		// Handles <exception> elements.		//		private static void HandleException (MemberCore mc,			DeclSpace ds, XmlElement seealso)		{			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.		//		private static Type FindDocumentedType (MemberCore mc, string name, DeclSpace ds, string cref)		{			bool isArray = 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);					isArray = true;				}			}			Type t = FindDocumentedTypeNonArray (mc, identifier, ds, cref);			if (t != null && isArray)				t = Array.CreateInstance (t, 0).GetType ();			return t;		}		private static Type FindDocumentedTypeNonArray (MemberCore mc, 			string identifier, DeclSpace ds, string cref)		{			switch (identifier) {			case "int":				return typeof (int);			case "uint":				return typeof (uint);			case "short":				return typeof (short);			case "ushort":				return typeof (ushort);			case "long":				return typeof (long);			case "ulong":				return typeof (ulong);			case "float":				return typeof (float);			case "double":				return typeof (double);			case "char":				return typeof (char);			case "decimal":				return typeof (decimal);			case "byte":				return typeof (byte);			case "sbyte":				return typeof (sbyte);			case "object":				return typeof (object);			case "bool":				return typeof (bool);			case "string":				return typeof (string);			case "void":				return typeof (void);			}			FullNamedExpression e = ds.LookupType (identifier, mc.Location, false);			if (e != null) {				if (!(e is TypeExpr))					return null;				return ((TypeExpr) e).Type;			}			int index = identifier.LastIndexOf ('.');			if (index < 0)				return null;			int warn;			Type parent = FindDocumentedType (mc, identifier.Substring (0, index), ds, cref);			if (parent == null)				return null;			// no need to detect warning 419 here			return FindDocumentedMember (mc, parent,				identifier.Substring (index + 1),				emptyParamList,				ds, out warn, cref) as Type;		}		//		// Returns a MemberInfo that is referenced in XML documentation		// (by "see" or "seealso" elements).		//		private static MemberInfo FindDocumentedMember (MemberCore mc,			Type type, string memberName, Type [] paramList, 			DeclSpace ds, out int warningType, string cref)		{			warningType = 0;			MethodSignature msig = new MethodSignature (memberName, null, paramList);			MemberInfo [] mis = type.FindMembers (				MemberTypes.All,				BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,				MethodSignature.method_signature_filter,				msig);			if (mis.Length > 0) {				if (IsAmbiguous (mis))					warningType = 419;				return mis [0];			}			if (paramList.Length == 0) {				// search for fields/events etc.				mis = type.FindMembers (					MemberTypes.All,					BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,					Type.FilterName,					memberName);				if (mis.Length == 0)					return null;				if (IsAmbiguous (mis))					warningType = 419;				return mis [0];			}			// search for operators (whose parameters exactly			// matches with the list) and possibly report CS1581.			string oper = null;			string returnTypeName = null;			if (memberName.StartsWith ("implicit operator ")) {				oper = "op_Implicit";				returnTypeName = memberName.Substring (18).Trim (wsChars);			}			else if (memberName.StartsWith ("explicit operator ")) {				oper = "op_Explicit";				returnTypeName = memberName.Substring (18).Trim (wsChars);			}			else if (memberName.StartsWith ("operator ")) {				oper = memberName.Substring (9).Trim (wsChars);				switch (oper) {				// either unary or binary				case "+":					oper = paramList.Length == 2 ?						Binary.oper_names [(int) Binary.Operator.Addition] :						Unary.oper_names [(int) Unary.Operator.UnaryPlus];					break;				case "-":					oper = paramList.Length == 2 ?						Binary.oper_names [(int) Binary.Operator.Subtraction] :						Unary.oper_names [(int) Unary.Operator.UnaryNegation];					break;				// unary				case "!":					oper = Unary.oper_names [(int) Unary.Operator.LogicalNot]; break;				case "~":					oper = Unary.oper_names [(int) Unary.Operator.OnesComplement]; break;									case "++":					oper = "op_Increment"; break;				case "--":					oper = "op_Decrement"; break;				case "true":					oper = "op_True"; break;				case "false":					oper = "op_False"; break;				// binary				case "*":					oper = Binary.oper_names [(int) Binary.Operator.Multiply]; break;				case "/":					oper = Binary.oper_names [(int) Binary.Operator.Division]; break;				case "%":					oper = Binary.oper_names [(int) Binary.Operator.Modulus]; break;				case "&":					oper = Binary.oper_names [(int) Binary.Operator.BitwiseAnd]; break;				case "|":					oper = Binary.oper_names [(int) Binary.Operator.BitwiseOr]; break;				case "^":					oper = Binary.oper_names [(int) Binary.Operator.ExclusiveOr]; break;				case "<<":					oper = Binary.oper_names [(int) Binary.Operator.LeftShift]; break;				case ">>":					oper = Binary.oper_names [(int) Binary.Operator.RightShift]; break;				case "==":					oper = Binary.oper_names [(int) Binary.Operator.Equality]; break;				case "!=":					oper = Binary.oper_names [(int) Binary.Operator.Inequality]; break;				case "<":					oper = Binary.oper_names [(int) Binary.Operator.LessThan]; break;				case ">":					oper = Binary.oper_names [(int) Binary.Operator.GreaterThan]; break;				case "<=":					oper = Binary.oper_names [(int) Binary.Operator.LessThanOrEqual]; break;				case ">=":					oper = Binary.oper_names [(int) Binary.Operator.GreaterThanOrEqual]; break;				default:					warningType = 1584;					Report.Warning (1020, 1, mc.Location, "Overloadable {0} operator is expected", paramList.Length == 2 ? "binary" : "unary");					Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",						mc.GetSignatureForError (), cref);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -