Mono.CSharp.DocUtil.HandleXrefCommon C# (CSharp) Method

HandleXrefCommon() private static method

private static HandleXrefCommon ( MemberCore mc, DeclSpace ds, XmlElement xref, Report Report ) : void
mc MemberCore
ds DeclSpace
xref System.Xml.XmlElement
Report Report
return void
		private static void HandleXrefCommon (MemberCore mc,
			DeclSpace ds, XmlElement xref, Report Report)
		{
			string cref = xref.GetAttribute ("cref").Trim (wsChars);
			// 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<System.Int32>
			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 ());
			}

			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
			}

			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
					}
				}
			} 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
				}
			}

			// 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);

			xref.SetAttribute ("cref", "!:" + name);
		}