// // Raised (and passed an XmlElement that contains the comment) // when GenerateDocComment is writing documentation expectedly. // // FIXME: with a few effort, it could be done with XmlReader, // that means removal of DOM use. // void CheckParametersComments(MemberCore member, IParametersMember paramMember, XmlElement el) { 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 (found_tags == null) { found_tags = new HashSet <string> (); } 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; } 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; } found_tags.Add(xname); } 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()); } } } }
// // Handles <typeparamref /> node // static void HandleTypeParamRef(MemberCore mc, XmlElement node) { if (!node.HasAttribute("name")) { return; } string tp_name = node.GetAttribute("name"); var member = mc; do { if (member.CurrentTypeParameters != null) { if (member.CurrentTypeParameters.Find(tp_name) != null) { return; } } member = member.Parent; } while (member != null); 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); }
// // Handles <typeparam /> node // void HandleTypeParam(MemberCore mc, XmlElement node) { if (!node.HasAttribute("name")) { return; } string tp_name = node.GetAttribute("name"); if (mc.CurrentTypeParameters != null) { foreach (var tp in mc.CurrentTypeParameters) { if (tp.Name == tp_name) { return; } } } // 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); }
private void FinalizeVirtualState(MemberCore m, bool updateModFlags) { string signature; MethodInfo methodInfo = GetMethodInfoFromCache(m, out signature); if (methodInfo != null) { switch (methodInfo.Type) { case VirtualType.Unknown: if (verbose) { Console.WriteLine("[Auto-sealing] Error with method {0}. Still has an unknown virtual type.", methodInfo.Member.GetSignatureForError()); } break; case VirtualType.FirstAndOnlyVirtual: // This the first and only virtual, it is as if the method was not virtual at all if (updateModFlags) { m.ModFlags &= ~Modifiers.VIRTUAL; methodInfo.Member.ModFlags &= ~Modifiers.VIRTUAL; } methodInfo.Type = VirtualType.NotVirtual; if (verbose) { Console.WriteLine("[Auto-sealing] Remove virtual on {0}", m.GetSignatureForError()); } break; case VirtualType.OverrideVirtual: // Set the override flag in case it was not set if (updateModFlags) { m.ModFlags &= ~Modifiers.VIRTUAL; m.ModFlags |= Modifiers.OVERRIDE; } if (verbose) { Console.WriteLine("[Auto-sealing] Make override on {0}", m.GetSignatureForError()); } break; case VirtualType.FirstVirtual: if ((m.Parent.ModFlags & Modifiers.SEALED) != 0) { // This case can happen if we could not track correctly the method earlier if (verbose) { Console.WriteLine("[Auto-sealing] Remove virtual (due to sealed class) on {0}", m.GetSignatureForError()); } m.ModFlags &= ~Modifiers.VIRTUAL; } break; } } }
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 = 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 = line_head + String.Join( line_head, split, 0, j); return(el); } catch (Exception ex) { 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))); } }
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 = XmlDocumentation; try { XmlElement el = doc.CreateElement("member"); el.SetAttribute("name", name); string normalized = mc.DocComment; el.InnerXml = normalized; string [] split = normalized.Split('\n'); el.InnerXml = line_head + String.Join(line_head, split); return(el); } catch (Exception ex) { 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))); } }
public InternalErrorException (MemberCore mc, Exception e) : base (mc.Location + " " + mc.GetSignatureForError (), e) { }
/// <summary> /// Resolve the constraints - but only resolve things into Expression's, not /// into actual types. /// </summary> public bool Resolve (MemberCore ec, TypeParameter tp, Report Report) { if (resolved) return true; if (ec == null) return false; iface_constraints = new ArrayList (2); // TODO: Too expensive allocation type_param_constraints = new ArrayList (); foreach (object obj in constraints) { if (HasConstructorConstraint) { Report.Error (401, loc, "The new() constraint must be the last constraint specified"); return false; } if (obj is SpecialConstraint) { SpecialConstraint sc = (SpecialConstraint) obj; if (sc == SpecialConstraint.Constructor) { if (!HasValueTypeConstraint) { attrs |= GenericParameterAttributes.DefaultConstructorConstraint; continue; } Report.Error (451, loc, "The `new()' constraint " + "cannot be used with the `struct' constraint"); return false; } if ((num_constraints > 0) || HasReferenceTypeConstraint || HasValueTypeConstraint) { Report.Error (449, loc, "The `class' or `struct' " + "constraint must be the first constraint specified"); return false; } if (sc == SpecialConstraint.ReferenceType) attrs |= GenericParameterAttributes.ReferenceTypeConstraint; else attrs |= GenericParameterAttributes.NotNullableValueTypeConstraint; continue; } int errors = Report.Errors; FullNamedExpression fn = ((Expression) obj).ResolveAsTypeStep (ec, false); if (fn == null) { if (errors != Report.Errors) return false; NamespaceEntry.Error_NamespaceNotFound (loc, ((Expression)obj).GetSignatureForError (), Report); return false; } TypeExpr expr; GenericTypeExpr cexpr = fn as GenericTypeExpr; if (cexpr != null) { expr = cexpr.ResolveAsBaseTerminal (ec, false); } else expr = ((Expression) obj).ResolveAsTypeTerminal (ec, false); if ((expr == null) || (expr.Type == null)) return false; if (!ec.IsAccessibleAs (fn.Type)) { Report.SymbolRelatedToPreviousError (fn.Type); Report.Error (703, loc, "Inconsistent accessibility: constraint type `{0}' is less accessible than `{1}'", fn.GetSignatureForError (), ec.GetSignatureForError ()); return false; } if (TypeManager.IsGenericParameter (expr.Type)) type_param_constraints.Add (expr); else if (expr.IsInterface) iface_constraints.Add (expr); else if (class_constraint != null || iface_constraints.Count != 0) { Report.Error (406, loc, "The class type constraint `{0}' must be listed before any other constraints. Consider moving type constraint to the beginning of the constraint list", expr.GetSignatureForError ()); return false; } else if (HasReferenceTypeConstraint || HasValueTypeConstraint) { Report.Error (450, loc, "`{0}': cannot specify both " + "a constraint class and the `class' " + "or `struct' constraint", expr.GetSignatureForError ()); return false; } else class_constraint = expr; // // Checks whether each generic method parameter constraint type // is valid with respect to T // if (tp != null && tp.Type.DeclaringMethod != null) { TypeManager.CheckTypeVariance (expr.Type, Variance.Contravariant, ec as MemberCore); } num_constraints++; } ArrayList list = new ArrayList (); foreach (TypeExpr iface_constraint in iface_constraints) { foreach (Type type in list) { if (!type.Equals (iface_constraint.Type)) continue; Report.Error (405, loc, "Duplicate constraint `{0}' for type " + "parameter `{1}'.", iface_constraint.GetSignatureForError (), name); return false; } list.Add (iface_constraint.Type); } foreach (TypeExpr expr in type_param_constraints) { foreach (Type type in list) { if (!type.Equals (expr.Type)) continue; Report.Error (405, loc, "Duplicate constraint `{0}' for type " + "parameter `{1}'.", expr.GetSignatureForError (), name); return false; } list.Add (expr.Type); } iface_constraint_types = new Type [list.Count]; list.CopyTo (iface_constraint_types, 0); if (class_constraint != null) { class_constraint_type = class_constraint.Type; if (class_constraint_type == null) return false; if (class_constraint_type.IsSealed) { if (class_constraint_type.IsAbstract) { Report.Error (717, loc, "`{0}' is not a valid constraint. Static classes cannot be used as constraints", TypeManager.CSharpName (class_constraint_type)); } else { Report.Error (701, loc, "`{0}' is not a valid constraint. A constraint must be an interface, " + "a non-sealed class or a type parameter", TypeManager.CSharpName(class_constraint_type)); } return false; } if ((class_constraint_type == TypeManager.array_type) || (class_constraint_type == TypeManager.delegate_type) || (class_constraint_type == TypeManager.enum_type) || (class_constraint_type == TypeManager.value_type) || (class_constraint_type == TypeManager.object_type) || class_constraint_type == TypeManager.multicast_delegate_type) { Report.Error (702, loc, "A constraint cannot be special class `{0}'", TypeManager.CSharpName (class_constraint_type)); return false; } if (TypeManager.IsDynamicType (class_constraint_type)) { Report.Error (1967, loc, "A constraint cannot be the dynamic type"); return false; } } if (class_constraint_type != null) effective_base_type = class_constraint_type; else if (HasValueTypeConstraint) effective_base_type = TypeManager.value_type; else effective_base_type = TypeManager.object_type; if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) attrs |= GenericParameterAttributes.DefaultConstructorConstraint; resolved = true; return true; }
private static MemberInfo FindDocumentedMemberNoNest ( 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 Report) { warning_type = 0; MemberInfo [] mis; if (param_list == null) { // search for fields/events etc. mis = TypeManager.MemberLookup (type, null, type, MemberTypes.All, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, 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 MemberInfo mi = mis [0]; Type expected = mi is MethodInfo ? ((MethodInfo) mi).ReturnType : mi is PropertyInfo ? ((PropertyInfo) mi).PropertyType : null; if (return_type_name != null) { Type 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]; }
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 = 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 = line_head + String.Join ( line_head, split, 0, j); return el; } catch (Exception ex) { 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)); } }
// // Processes "see" or "seealso" elements from cref attribute. // void HandleXrefCommon (MemberCore mc, TypeContainer ds, XmlElement xref) { string cref = xref.GetAttribute ("cref"); // when, XmlReader, "if (cref == null)" if (!xref.HasAttribute ("cref")) return; // Nothing to be resolved the reference is marked explicitly if (cref.Length > 2 && cref [1] == ':') return; // 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; } MemberSpec member; string prefix = null; FullNamedExpression fne = null; // // 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; } 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); } 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; } 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; } } // Continue with parent type for nested types if (member == null) { type = type.DeclaringType; } else { type = null; } } while (type != null); 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 (parameters_match == parsed_param_count + 1) { Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref); } } } } 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 (); } xref.SetAttribute ("cref", cref); }
// // Handles <typeparam /> node // static void HandleTypeParam (MemberCore mc, XmlElement node) { if (!node.HasAttribute ("name")) return; string tp_name = node.GetAttribute ("name"); if (mc.CurrentTypeParameters != null) { if (mc.CurrentTypeParameters.Find (tp_name) != null) return; } // 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); }
public override void AddNameToContainer (MemberCore symbol, string name) { if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) { if (symbol is TypeParameter) { Report.Error (694, symbol.Location, "Type parameter `{0}' has same name as containing type, or method", symbol.GetSignatureForError ()); return; } InterfaceMemberBase imb = symbol as InterfaceMemberBase; if (imb == null || !imb.IsExplicitImpl) { Report.SymbolRelatedToPreviousError (this); Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type", symbol.GetSignatureForError ()); return; } } base.AddNameToContainer (symbol, name); }
protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member) { Report.SymbolRelatedToPreviousError (base_member); Report.Error (507, member.Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'", member.GetSignatureForError (), ModifiersExtensions.AccessibilityName (base_member.Modifiers), base_member.GetSignatureForError ()); }
public static void Error_CyclicDeclaration (MemberCore mc) { Report.Error (110, mc.Location, "The evaluation of the constant value for `{0}' involves a circular definition", mc.GetSignatureForError ()); }
public void Error_UnexpectedKind(Report r, MemberCore mc, string expected, string was, Location loc) { string name; if (mc != null) name = mc.GetSignatureForError (); else name = GetSignatureForError (); r.Error (118, loc, "`{0}' is a `{1}' but a `{2}' was expected", name, was, expected); }
private MethodInfo GetMethodInfoFromCache(MemberCore m, out string signature) { signature = "unknown"; TypeSpec containerType = m.Parent.CurrentType; Dictionary<string, MethodInfo> listOfMethods; if (methodsByTypes.TryGetValue(containerType, out listOfMethods) == false) { return null; } signature = GetSignature(m); MethodInfo methodInfo = listOfMethods[signature]; if (methodInfo == null) { if (verbose) { Console.WriteLine("[Auto-sealing] Error when looking for method {0}.", m.GetSignatureForError()); } } else if (methodInfo.Member != m) { if (verbose) { Console.WriteLine("[Auto-sealing] Error when matching method {0}.", m.GetSignatureForError()); } } return methodInfo; }
private void AddMemberToList (MemberCore mc, List<MemberCore> alist, bool isexplicit) { if (ordered_explicit_member_list == null) { ordered_explicit_member_list = new List<MemberCore> (); ordered_member_list = new List<MemberCore> (); } if (isexplicit) { if (Kind == MemberKind.Interface) { Report.Error (541, mc.Location, "`{0}': explicit interface declaration can only be declared in a class or struct", mc.GetSignatureForError ()); } ordered_explicit_member_list.Add (mc); alist.Insert (0, mc); } else { ordered_member_list.Add (mc); alist.Add (mc); } }
public static void Error_CyclicDeclaration(MemberCore mc, Report Report) { Report.Error(110, mc.Location, "The evaluation of the constant value for `{0}' involves a circular definition", mc.GetSignatureForError()); }
private static MemberInfo FindDocumentedMemberNoNest( 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 Report) { warning_type = 0; MemberInfo [] mis; if (param_list == null) { // search for fields/events etc. mis = TypeManager.MemberLookup(type, null, type, MemberTypes.All, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, 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 } MemberInfo mi = mis [0]; Type expected = mi is MethodInfo ? ((MethodInfo)mi).ReturnType : mi is PropertyInfo ? ((PropertyInfo)mi).PropertyType : null; if (return_type_name != null) { Type 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]); }
public Constant ResolveAsConstant (EmitContext ec, MemberCore mc) { Expression e = Resolve (ec); if (e == null) return null; Constant c = e as Constant; if (c != null) return c; if (type != null && TypeManager.IsReferenceType (type)) Const.Error_ConstantCanBeInitializedWithNullOnly (type, loc, mc.GetSignatureForError ()); else Const.Error_ExpressionMustBeConstant (loc, mc.GetSignatureForError ()); return null; }
// // Generates xml doc comments (if any), and if required, // handle warning report. // internal static void GenerateDocComment(MemberCore mc, DeclSpace ds, Report Report) { 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); } } } // 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); } } n.WriteTo(RootContext.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()); } } }
// // Handles <typeparamref /> node // static void HandleTypeParamRef (MemberCore mc, XmlElement node) { if (!node.HasAttribute ("name")) return; string tp_name = node.GetAttribute ("name"); var member = mc; do { if (member.CurrentTypeParameters != null) { if (member.CurrentTypeParameters.Find (tp_name) != null) return; } member = member.Parent; } while (member != null); 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); }
// // 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); }
// // Raised (and passed an XmlElement that contains the comment) // when GenerateDocComment is writing documentation expectedly. // // FIXME: with a few effort, it could be done with XmlReader, // that means removal of DOM use. // void CheckParametersComments (MemberCore member, IParametersMember paramMember, XmlElement el) { 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 (found_tags == null) { found_tags = new HashSet<string> (); } 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; } 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; } found_tags.Add (xname); } 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 ()); } } }
// // Generates xml doc comments (if any), and if required, // handle warning report. // internal static void GenerateDocComment(MemberCore mc, DeclSpace ds, Report Report) { 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); } // 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); } n.WriteTo (RootContext.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 ()); } }
/// <summary> /// Adds the member to defined_names table. It tests for duplications and enclosing name conflicts /// </summary> protected virtual bool AddToContainer (MemberCore symbol, string name) { MemberCore mc; if (!defined_names.TryGetValue (name, out mc)) { defined_names.Add (name, symbol); return true; } if (((mc.ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0) return true; if (symbol.EnableOverloadChecks (mc)) return true; InterfaceMemberBase im = mc as InterfaceMemberBase; if (im != null && im.IsExplicitImpl) return true; Report.SymbolRelatedToPreviousError (mc); if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) { Error_MissingPartialModifier (symbol); return false; } if (this is ModuleContainer) { Report.Error (101, symbol.Location, "The namespace `{0}' already contains a definition for `{1}'", ((DeclSpace)symbol).NamespaceEntry.GetSignatureForError (), symbol.MemberName.Name); } else if (symbol is TypeParameter) { Report.Error (692, symbol.Location, "Duplicate type parameter `{0}'", symbol.GetSignatureForError ()); } else { Report.Error (102, symbol.Location, "The type `{0}' already contains a definition for `{1}'", GetSignatureForError (), symbol.MemberName.Name); } return false; }
// // 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 (GlobalRootNamespace.Instance.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); }
// // Processes "see" or "seealso" elements from cref attribute. // void HandleXrefCommon(MemberCore mc, XmlElement xref) { string cref = xref.GetAttribute("cref"); // when, XmlReader, "if (cref == null)" if (!xref.HasAttribute("cref")) { return; } // Nothing to be resolved the reference is marked explicitly if (cref.Length > 2 && cref [1] == ':') { return; } // 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)); var source_file = new CompilationSourceFile(doc_module, mc.Location.SourceFile); var report = new Report(doc_module.Compiler, new NullReportPrinter()); if (session == null) { session = new ParserSession { UseJayGlobalArrays = true } } ; SeekableStreamReader seekable = new SeekableStreamReader(s, encoding, session.StreamReaderBuffer); var parser = new CSharpParser(seekable, source_file, report, session); 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; } MemberSpec member; string prefix = null; FullNamedExpression fne = null; // // 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 NamespaceExpression; 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; } if (ParsedParameters != null) { var old_printer = mc.Module.Compiler.Report.SetPrinter(new NullReportPrinter()); try { var context = new DocumentationMemberContext(mc, ParsedName ?? MemberName.Null); foreach (var pp in ParsedParameters) { pp.Resolve(context); } } finally { mc.Module.Compiler.Report.SetPrinter(old_printer); } } 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; } 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; } var pm_params = pm.Parameters; int i; for (i = 0; i < parsed_param_count; ++i) { var pparam = ParsedParameters[i]; if (i >= pm_params.Count || pparam == null || pparam.TypeSpec == null || !TypeSpecComparer.Override.IsEqual(pparam.TypeSpec, pm_params.Types[i]) || (pparam.Modifier & Parameter.Modifier.RefOutMask) != (pm_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) { 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_params.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; } } // Continue with parent type for nested types if (member == null) { type = type.DeclaringType; } else { type = null; } } while (type != null); 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 (parameters_match == parsed_param_count + 1) { Report.Warning(1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref); } } } } 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(); } xref.SetAttribute("cref", cref); }
public InternalErrorException(MemberCore mc, Exception e) : base(mc.Location + " " + mc.GetSignatureForError(), e) { }
public string GetSignatureForError() { return(host.GetSignatureForError()); }
public void SymbolRelatedToPreviousError(MemberCore mc) { SymbolRelatedToPreviousError(mc.Location, mc.GetSignatureForError()); }
public void SymbolRelatedToPreviousError (MemberCore mc) { SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ()); }
protected void Error_MissingPartialModifier (MemberCore type) { Report.Error (260, type.Location, "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists", type.GetSignatureForError ()); }
public override void Visit (MemberCore member) { Console.WriteLine ("Unknown member:"); Console.WriteLine (member.GetType () + "-> Member {0}", member.GetSignatureForError ()); }
public void AddMember (MemberCore symbol) { if (symbol.MemberName.ExplicitInterface != null) { if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) { Report.Error (541, symbol.Location, "`{0}': explicit interface declaration can only be declared in a class or struct", symbol.GetSignatureForError ()); } } AddNameToContainer (symbol, symbol.MemberName.Basename); members.Add (symbol); }
// // Performs the validation on a Method's modifiers (properties have // the same properties). // // TODO: Why is it not done at parse stage, move to Modifiers::Check // public bool MethodModifiersValid (MemberCore mc) { const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE); const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL); bool ok = true; var flags = mc.ModFlags; // // At most one of static, virtual or override // if ((flags & Modifiers.STATIC) != 0){ if ((flags & vao) != 0){ Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract", mc.GetSignatureForError ()); ok = false; } } if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){ Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual", mc.GetSignatureForError ()); ok = false; } // // If the declaration includes the abstract modifier, then the // declaration does not include static, virtual or extern // if ((flags & Modifiers.ABSTRACT) != 0){ if ((flags & Modifiers.EXTERN) != 0){ Report.Error ( 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ()); ok = false; } if ((flags & Modifiers.SEALED) != 0) { Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ()); ok = false; } if ((flags & Modifiers.VIRTUAL) != 0){ Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ()); ok = false; } if ((ModFlags & Modifiers.ABSTRACT) == 0){ Report.SymbolRelatedToPreviousError (this); Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'", mc.GetSignatureForError (), GetSignatureForError ()); ok = false; } } if ((flags & Modifiers.PRIVATE) != 0){ if ((flags & vao) != 0){ Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ()); ok = false; } } if ((flags & Modifiers.SEALED) != 0){ if ((flags & Modifiers.OVERRIDE) == 0){ Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ()); ok = false; } } return ok; }
public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression) { if ((field.ModFlags & Modifiers.STATIC) == 0 && !HasExplicitConstructor ()) { Report.Error (8054, field.Location, "`{0}': Structs without explicit constructors cannot contain members with initializers", field.GetSignatureForError ()); return; } base.RegisterFieldForInitialization (field, expression); }
public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression) { if ((field.ModFlags & Modifiers.STATIC) == 0) { Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers", field.GetSignatureForError ()); return; } base.RegisterFieldForInitialization (field, expression); }
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 = XmlDocumentation; try { XmlElement el = doc.CreateElement ("member"); el.SetAttribute ("name", name); string normalized = mc.DocComment; el.InnerXml = normalized; string [] split = normalized.Split ('\n'); el.InnerXml = line_head + String.Join (line_head, split); return el; } catch (Exception ex) { 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)); } }
protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member) { var base_modifiers = base_member.Modifiers; // Remove internal modifier from types which are not internally accessible if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) && !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly)) base_modifiers = Modifiers.PROTECTED; Report.SymbolRelatedToPreviousError (base_member); Report.Error (507, member.Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'", member.GetSignatureForError (), ModifiersExtensions.AccessibilityName (base_modifiers), base_member.GetSignatureForError ()); }
private MethodInfo GetMethodInfoFromCache(MemberCore m, out string signature) { signature = "unknown"; TypeSpec containerType = m.Parent.CurrentType; Dictionary <string, MethodInfo> listOfMethods; if (methodsByTypes.TryGetValue(containerType, out listOfMethods) == false) { return(null); } signature = GetSignature(m); MethodInfo methodInfo = listOfMethods[signature]; if (methodInfo == null) { if (verbose) { Console.WriteLine("[Auto-sealing] Error when looking for method {0}.", m.GetSignatureForError()); } } else if (methodInfo.Member != m) { if (verbose) { Console.WriteLine("[Auto-sealing] Error when matching method {0}.", m.GetSignatureForError()); } } return(methodInfo); }
// // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts // public virtual void AddNameToContainer (MemberCore symbol, string name) { if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0) return; MemberCore mc; if (!PartialContainer.defined_names.TryGetValue (name, out mc)) { PartialContainer.defined_names.Add (name, symbol); return; } if (symbol.EnableOverloadChecks (mc)) return; InterfaceMemberBase im = mc as InterfaceMemberBase; if (im != null && im.IsExplicitImpl) return; Report.SymbolRelatedToPreviousError (mc); if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) { Error_MissingPartialModifier (symbol); return; } if (symbol is TypeParameter) { Report.Error (692, symbol.Location, "Duplicate type parameter `{0}'", symbol.GetSignatureForError ()); } else { Report.Error (102, symbol.Location, "The type `{0}' already contains a definition for `{1}'", GetSignatureForError (), name); } return; }
public bool CheckExistingMembersOverloads (MemberCore member, string name, ParametersCompiled parameters, Report Report) { ArrayList entries = (ArrayList)member_hash [name]; if (entries == null) return true; int method_param_count = parameters.Count; for (int i = entries.Count - 1; i >= 0; --i) { CacheEntry ce = (CacheEntry) entries [i]; if (ce.Container != member.Parent.PartialContainer) return true; Type [] p_types; AParametersCollection pd; if ((ce.EntryType & EntryType.Property) != 0) { pd = TypeManager.GetParameterData ((PropertyInfo) ce.Member); p_types = pd.Types; } else { MethodBase mb = (MethodBase) ce.Member; // TODO: This is more like a hack, because we are adding generic methods // twice with and without arity name if (TypeManager.IsGenericMethod (mb) && !member.MemberName.IsGeneric) continue; pd = TypeManager.GetParameterData (mb); p_types = pd.Types; } if (p_types.Length != method_param_count) continue; if (method_param_count > 0) { int ii = method_param_count - 1; Type type_a, type_b; do { type_a = parameters.Types [ii]; type_b = p_types [ii]; #if GMCS_SOURCE if (TypeManager.IsGenericParameter (type_a) && type_a.DeclaringMethod != null) type_a = typeof (TypeParameter); if (TypeManager.IsGenericParameter (type_b) && type_b.DeclaringMethod != null) type_b = typeof (TypeParameter); #endif if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) != (parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF)) type_a = null; } while (type_a == type_b && ii-- != 0); if (ii >= 0) continue; // // Operators can differ in return type only // if (member is Operator) { Operator op = TypeManager.GetMethod ((MethodBase) ce.Member) as Operator; if (op != null && op.ReturnType != ((Operator) member).ReturnType) continue; } // // Report difference in parameter modifiers only // if (pd != null && member is MethodCore) { ii = method_param_count; while (ii-- != 0 && parameters.FixedParameters [ii].ModFlags == pd.FixedParameters [ii].ModFlags && parameters.ExtensionMethodType == pd.ExtensionMethodType); if (ii >= 0) { MethodCore mc = TypeManager.GetMethod ((MethodBase) ce.Member) as MethodCore; Report.SymbolRelatedToPreviousError (ce.Member); if ((member.ModFlags & Modifiers.PARTIAL) != 0 && (mc.ModFlags & Modifiers.PARTIAL) != 0) { if (parameters.HasParams || pd.HasParams) { Report.Error (758, member.Location, "A partial method declaration and partial method implementation cannot differ on use of `params' modifier"); } else { Report.Error (755, member.Location, "A partial method declaration and partial method implementation must be both an extension method or neither"); } } else { if (member is Constructor) { Report.Error (851, member.Location, "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only", member.GetSignatureForError ()); } else { Report.Error (663, member.Location, "Overloaded method `{0}' cannot differ on use of parameter modifiers only", member.GetSignatureForError ()); } } return false; } } } if ((ce.EntryType & EntryType.Method) != 0) { Method method_a = member as Method; Method method_b = TypeManager.GetMethod ((MethodBase) ce.Member) as Method; if (method_a != null && method_b != null && (method_a.ModFlags & method_b.ModFlags & Modifiers.PARTIAL) != 0) { const int partial_modifiers = Modifiers.STATIC | Modifiers.UNSAFE; if (method_a.IsPartialDefinition == method_b.IsPartialImplementation) { if ((method_a.ModFlags & partial_modifiers) == (method_b.ModFlags & partial_modifiers) || method_a.Parent.IsUnsafe && method_b.Parent.IsUnsafe) { if (method_a.IsPartialImplementation) { method_a.SetPartialDefinition (method_b); entries.RemoveAt (i); } else { method_b.SetPartialDefinition (method_a); } continue; } if ((method_a.ModFlags & Modifiers.STATIC) != (method_b.ModFlags & Modifiers.STATIC)) { Report.SymbolRelatedToPreviousError (ce.Member); Report.Error (763, member.Location, "A partial method declaration and partial method implementation must be both `static' or neither"); } Report.SymbolRelatedToPreviousError (ce.Member); Report.Error (764, member.Location, "A partial method declaration and partial method implementation must be both `unsafe' or neither"); return false; } Report.SymbolRelatedToPreviousError (ce.Member); if (method_a.IsPartialDefinition) { Report.Error (756, member.Location, "A partial method `{0}' declaration is already defined", member.GetSignatureForError ()); } Report.Error (757, member.Location, "A partial method `{0}' implementation is already defined", member.GetSignatureForError ()); return false; } Report.SymbolRelatedToPreviousError (ce.Member); IMethodData duplicate_member = TypeManager.GetMethod ((MethodBase) ce.Member); if (member is Operator && duplicate_member is Operator) { Report.Error (557, member.Location, "Duplicate user-defined conversion in type `{0}'", member.Parent.GetSignatureForError ()); return false; } bool is_reserved_a = member is AbstractPropertyEventMethod || member is Operator; bool is_reserved_b = duplicate_member is AbstractPropertyEventMethod || duplicate_member is Operator; if (is_reserved_a || is_reserved_b) { Report.Error (82, member.Location, "A member `{0}' is already reserved", is_reserved_a ? TypeManager.GetFullNameSignature (ce.Member) : member.GetSignatureForError ()); return false; } } else { Report.SymbolRelatedToPreviousError (ce.Member); } Report.Error (111, member.Location, "A member `{0}' is already defined. Rename this member or use different parameter types", member.GetSignatureForError ()); return false; } return true; }