public void SymbolRelatedToPreviousError(Type type) { if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport) { return; } type = TypeManager.DropGenericTypeArguments(type); if (TypeManager.IsGenericParameter(type)) { TypeParameter tp = TypeManager.LookupTypeParameter(type); if (tp != null) { SymbolRelatedToPreviousError(tp.Location, ""); return; } } if (type is TypeBuilder) { DeclSpace temp_ds = TypeManager.LookupDeclSpace(type); SymbolRelatedToPreviousError(temp_ds.Location, TypeManager.CSharpName(type)); } else if (TypeManager.HasElementType(type)) { SymbolRelatedToPreviousError(TypeManager.GetElementType(type)); } else { SymbolRelatedToPreviousError(type.Assembly.Location, TypeManager.CSharpName(type)); } }
public Const(DeclSpace parent, FullNamedExpression type, string name, Expression expr, int mod_flags, Attributes attrs, Location loc) : base(parent, type, mod_flags, AllowedModifiers, new MemberName(name, loc), attrs) { initializer = expr; ModFlags |= Modifiers.STATIC; }
public override EmitContext CreateEmitContext(DeclSpace tc, ILGenerator ig) { EmitContext ec = new EmitContext( this, tc, this.ds, Location, ig, MemberType, ModFlags, false); ec.CurrentAnonymousMethod = host.Iterator; return(ec); }
private NamespaceEntry(NamespaceEntry parent, CompilationUnit file, Namespace ns, bool slave) { this.parent = parent; this.file = file; this.IsImplicit = true; this.ns = ns; this.SlaveDeclSpace = slave ? new RootDeclSpace(this) : null; }
public void AddDeclSpace(string name, DeclSpace ds) { if (declspaces == null) { declspaces = new HybridDictionary(); } declspaces.Add(name, ds); }
protected FieldBase (DeclSpace parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) : base (parent, null, type, mod, allowed_mod | Modifiers.ABSTRACT, Modifiers.PRIVATE, name, attrs) { if ((mod & Modifiers.ABSTRACT) != 0) Report.Error (681, Location, "The modifier 'abstract' is not valid on fields. Try using a property instead"); }
// // Generates xml doc comments (if any), and if required, // handle warning report. // internal void GenerateDocumentationForMember(MemberCore mc) { string name = mc.DocCommentHeader + mc.GetSignatureForDocumentation(); 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); } // 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 DeclSpace ds_target = mc as DeclSpace; 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); } } n.WriteTo(XmlCommentOutput); }
protected override bool AddMemberType(DeclSpace ds) { if (!AddToContainer(ds, ds.Name)) { return(false); } ds.NamespaceEntry.NS.AddDeclSpace(ds.Basename, ds); return(true); }
public FullNamedExpression Lookup(DeclSpace ds, string name, Location loc) { if (namespaces.Contains(name)) { return((Namespace)namespaces [name]); } return(LookupType(name, loc)); }
public Enum(NamespaceEntry ns, DeclSpace parent, TypeExpr type, int mod_flags, MemberName name, Attributes attrs) : base(ns, parent, name, attrs, Kind.Enum) { this.base_type = type; int accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE; ModFlags = Modifiers.Check(AllowedModifiers, mod_flags, accmods, Location); }
public Enum(NamespaceContainer ns, DeclSpace parent, TypeExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) : base(ns, parent, name, attrs, MemberKind.Enum) { underlying_type_expr = type; var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE; ModFlags = ModifiersExtensions.Check(AllowedModifiers, mod_flags, accmods, Location, Report); spec = new EnumSpec(null, this, null, null, ModFlags); }
static public void PopulateCoreType(TypeContainer root, string name) { DeclSpace ds = (DeclSpace)root.GetDefinition(name); // Core type was imported if (ds == null) { return; } ds.Define(); }
public Delegate(NamespaceEntry ns, DeclSpace parent, FullNamedExpression type, int mod_flags, MemberName name, ParametersCompiled param_list, Attributes attrs) : base(ns, parent, name, attrs, Kind.Delegate) { this.ReturnType = type; ModFlags = Modifiers.Check(AllowedModifiers, mod_flags, IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, name.Location, Report); Parameters = param_list; }
TypeExpr LookupType(string name, Location loc) { if (cached_types.Contains(name)) { return(cached_types [name] as TypeExpr); } Type t = null; if (declspaces != null) { DeclSpace tdecl = declspaces [name] as DeclSpace; if (tdecl != null) { // // Note that this is not: // // t = tdecl.DefineType () // // This is to make it somewhat more useful when a DefineType // fails due to problems in nested types (more useful in the sense // of fewer misleading error messages) // tdecl.DefineType(); t = tdecl.TypeBuilder; if (RootContext.EvalMode) { // Replace the TypeBuilder with a System.Type, as // Reflection.Emit fails otherwise (we end up pretty // much with Random type definitions later on). Type tt = t.Assembly.GetType(t.Name); if (tt != null) { t = tt; } } } } string lookup = t != null ? t.FullName : (fullname.Length == 0 ? name : fullname + "." + name); Type rt = root.LookupTypeReflection(lookup, loc); // HACK: loc.IsNull when the type is core type if (t == null || (rt != null && loc.IsNull)) { t = rt; } TypeExpr te = t == null ? null : new TypeExpression(t, Location.Null); cached_types [name] = te; return(te); }
public Delegate(NamespaceContainer ns, DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, ParametersCompiled param_list, Attributes attrs) : base(ns, parent, name, attrs, MemberKind.Delegate) { this.ReturnType = type; ModFlags = ModifiersExtensions.Check(AllowedModifiers, mod_flags, IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, name.Location, Report); parameters = param_list; spec = new TypeSpec(Kind, null, this, null, ModFlags | Modifiers.SEALED); }
public FullNamedExpression LookupNamespaceOrType(DeclSpace ds, string name, Location loc, bool ignore_cs0104) { // Precondition: Only simple names (no dots) will be looked up with this function. FullNamedExpression resolved = null; for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) { if ((resolved = curr_ns.Lookup(ds, name, loc, ignore_cs0104)) != null) { break; } } return(resolved); }
public void SymbolRelatedToPreviousError(MemberInfo mi) { if (reporting_disabled > 0 || !printer.HasRelatedSymbolSupport) { return; } Type dt = TypeManager.DropGenericTypeArguments(mi.DeclaringType); if (TypeManager.IsDelegateType(dt)) { SymbolRelatedToPreviousError(dt); return; } DeclSpace temp_ds = TypeManager.LookupDeclSpace(dt); if (temp_ds == null) { SymbolRelatedToPreviousError(dt.Assembly.Location, TypeManager.GetFullNameSignature(mi)); } else { MethodBase mb = mi as MethodBase; if (mb != null) { mb = TypeManager.DropGenericMethodArguments(mb); IMethodData md = TypeManager.GetMethod(mb); if (md != null) { SymbolRelatedToPreviousError(md.Location, md.GetSignatureForError()); } return; } // FIXME: Completely wrong, it has to use FindMembers MemberCore mc = temp_ds.GetDefinition(mi.Name); if (mc != null) { SymbolRelatedToPreviousError(mc); } } }
// // Returns a MemberInfo that is referenced in XML documentation // (by "see" or "seealso" elements). // private static FoundMember FindDocumentedMember(MemberCore mc, Type type, string member_name, Type [] param_list, DeclSpace ds, out int warning_type, string cref, bool warn419, string name_for_error, Report r) { for (; type != null; type = type.DeclaringType) { MemberInfo mi = FindDocumentedMemberNoNest( mc, type, member_name, param_list, ds, out warning_type, cref, warn419, name_for_error, r); if (mi != null) { return(new FoundMember(type, mi)); } } warning_type = 0; return(FoundMember.Empty); }
// // Returns a MemberInfo that is referenced in XML documentation // (by "see" or "seealso" elements). // 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) { // 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); }
public NamespaceEntry(NamespaceEntry parent, CompilationUnit file, string name) { this.parent = parent; this.file = file; entries.Add(this); if (parent != null) { ns = parent.NS.GetNamespace(name, true); } else if (name != null) { ns = RootNamespace.Global.GetNamespace(name, true); } else { ns = RootNamespace.Global; } SlaveDeclSpace = new RootDeclSpace(this); }
// // returns a full runtime type name from a name which might // be C# specific type name. // 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(t); } return(t); }
public NamespaceEntry(ModuleContainer ctx, NamespaceEntry parent, CompilationUnit file, string name) { this.ctx = ctx; this.parent = parent; this.file = file; entries.Add(this); if (parent != null) { ns = parent.NS.GetNamespace(name, true); } else if (name != null) { ns = ctx.GlobalRootNamespace.GetNamespace(name, true); } else { ns = ctx.GlobalRootNamespace; } SlaveDeclSpace = new RootDeclSpace(this); }
// // 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 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; } } Type t = FindDocumentedTypeNonArray(mc, identifier, ds, cref); if (t != null && is_array) { t = Array.CreateInstance(t, 0).GetType(); } return(t); }
public override Type LookupTypeReflection(string name, Location loc) { Type found_type = base.LookupTypeReflection(name, loc); if (modules != null) { foreach (Module module in modules) { Type t = module.GetType(name); if (t == null) { continue; } if (found_type == null) { found_type = t; continue; } Report.SymbolRelatedToPreviousError(found_type); if (loc.IsNull) { DeclSpace ds = TypeManager.LookupDeclSpace(t); Report.Warning(1685, 1, ds.Location, "The type `{0}' conflicts with the predefined type `{1}' and will be ignored", ds.GetSignatureForError(), TypeManager.CSharpName(found_type)); return(found_type); } Report.SymbolRelatedToPreviousError(t); Report.Warning(436, 2, loc, "The type `{0}' conflicts with the imported type `{1}'. Ignoring the imported type definition", TypeManager.CSharpName(t), TypeManager.CSharpName(found_type)); return(t); } } return(found_type); }
public virtual void Error_NamespaceDoesNotExist(DeclSpace ds, Location loc, string name) { if (name.IndexOf('`') > 0) { FullNamedExpression retval = Lookup(ds, SimpleName.RemoveGenericArity(name), loc); if (retval != null) { Error_TypeArgumentsCannotBeUsed(retval, loc); return; } } else { Type t = LookForAnyGenericType(name); if (t != null) { Error_InvalidNumberOfTypeArguments(t, loc); return; } } Report.Error(234, loc, "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?", name, GetSignatureForError()); }
// TypeContainer // // Generates xml doc comments (if any), and if required, // handle warning report. // internal static void GenerateTypeDocComment(TypeContainer t, DeclSpace ds, Report Report) { GenerateDocComment(t, ds, Report); 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.Constants != null) { foreach (Const c in t.Constants) { c.GenerateDocComment(t); } } if (t.Fields != null) { foreach (FieldBase 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 (MethodOrOperator m in t.Methods) { m.GenerateDocComment(t); } } if (t.Operators != null) { foreach (Operator o in t.Operators) { o.GenerateDocComment(t); } } }
private static TypeSpec FindDocumentedTypeNonArray(MemberCore mc, string identifier, DeclSpace ds, string cref, Report r) { switch (identifier) { case "int": return(TypeManager.int32_type); case "uint": return(TypeManager.uint32_type); case "short": return(TypeManager.short_type);; case "ushort": return(TypeManager.ushort_type); case "long": return(TypeManager.int64_type); case "ulong": return(TypeManager.uint64_type);; case "float": return(TypeManager.float_type);; case "double": return(TypeManager.double_type); case "char": return(TypeManager.char_type);; case "decimal": return(TypeManager.decimal_type);; case "byte": return(TypeManager.byte_type);; case "sbyte": return(TypeManager.sbyte_type);; case "object": return(TypeManager.object_type);; case "bool": return(TypeManager.bool_type);; case "string": return(TypeManager.string_type);; case "void": return(TypeManager.void_type);; } 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); } 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.Compiler, typeName, 0, true, mc.Location); if (te != null) { return(te.Type); } } 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); }
// 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)); }
// // Processes "see" or "seealso" elements. // Checks cref attribute. // 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); }
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; } if (found == null) { return(null); } if (warn419 && found.Count > 1) { Report419(mc, name_for_error, found.ToArray(), Report); } 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]; * } * * MethodSignature msig = new MethodSignature (member_name, null, param_list); * mis = FindMethodBase (type, * BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, * msig); * * if (warn419 && mis.Length > 0) { * if (IsAmbiguous (mis)) * Report419 (mc, name_for_error, mis, Report); * return mis [0]; * } * * // 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 mis [0]; */ }