public Warning ( int code, int level, Mono.CSharp.Location loc, string message ) : void | ||
code | int | |
level | int | |
loc | Mono.CSharp.Location | |
message | string | |
Результат | void |
protected override bool CheckBase() { if (!base.CheckBase()) { return(false); } MemberSpec candidate; bool overrides = false; var conflict_symbol = MemberCache.FindBaseMember(this, out candidate, ref overrides); if (conflict_symbol == null) { conflict_symbol = candidate; } if (conflict_symbol == null) { if ((ModFlags & Modifiers.NEW) != 0) { Report.Warning(109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError()); } } else { if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) { Report.SymbolRelatedToPreviousError(conflict_symbol); Report.Warning(108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", GetSignatureForError(), conflict_symbol.GetSignatureForError()); } if (conflict_symbol.IsAbstract) { Report.SymbolRelatedToPreviousError(conflict_symbol); Report.Error(533, Location, "`{0}' hides inherited abstract member `{1}'", GetSignatureForError(), conflict_symbol.GetSignatureForError()); } } return(true); }
protected override bool VerifyClsCompliance() { if (!base.VerifyClsCompliance()) { return(false); } switch (UnderlyingType.BuiltinType) { case BuiltinTypeSpec.Type.UInt: case BuiltinTypeSpec.Type.ULong: case BuiltinTypeSpec.Type.UShort: Report.Warning(3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError(), TypeManager.CSharpName(UnderlyingType)); break; } return(true); }
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))); } }
// // Generates xml doc comments (if any), and if required, // handle warning report. // internal virtual void GenerateDocComment(DocumentationBuilder builder) { if (DocComment == null) { if (IsExposedFromAssembly()) { Constructor c = this as Constructor; if (c == null || !c.IsDefault()) { Report.Warning(1591, 4, Location, "Missing XML comment for publicly visible type or member `{0}'", GetSignatureForError()); } } return; } try { builder.GenerateDocumentationForMember(this); } catch (Exception e) { throw new InternalErrorException(this, e); } }
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); }
protected void Warning_IdentifierNotCompliant() { Report.Warning(3008, 1, MemberName.Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError()); }
protected void ResolveAssemblySecurityAttributes() { string key_file = null; string key_container = null; if (module.OptAttributes != null) { foreach (Attribute a in module.OptAttributes.Attrs) { // cannot rely on any resolve-based members before you call Resolve if (a.ExplicitTarget != "assembly") { continue; } // TODO: This code is buggy: comparing Attribute name without resolving is wrong. // However, this is invoked by CodeGen.Init, when none of the namespaces // are loaded yet. // TODO: Does not handle quoted attributes properly switch (a.Name) { case "AssemblyKeyFile": case "AssemblyKeyFileAttribute": case "System.Reflection.AssemblyKeyFileAttribute": if (Compiler.Settings.StrongNameKeyFile != null) { Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError()); Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", "keyfile", "System.Reflection.AssemblyKeyFileAttribute"); } else { string value = a.GetString(); if (!string.IsNullOrEmpty(value)) { Error_ObsoleteSecurityAttribute(a, "keyfile"); key_file = value; } } break; case "AssemblyKeyName": case "AssemblyKeyNameAttribute": case "System.Reflection.AssemblyKeyNameAttribute": if (Compiler.Settings.StrongNameKeyContainer != null) { Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError()); Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", "keycontainer", "System.Reflection.AssemblyKeyNameAttribute"); } else { string value = a.GetString(); if (!string.IsNullOrEmpty(value)) { Error_ObsoleteSecurityAttribute(a, "keycontainer"); key_container = value; } } break; case "AssemblyDelaySign": case "AssemblyDelaySignAttribute": case "System.Reflection.AssemblyDelaySignAttribute": bool b = a.GetBoolean(); if (b) { Error_ObsoleteSecurityAttribute(a, "delaysign"); } delay_sign = b; break; } } } // We came here only to report assembly attributes warnings if (public_key != null) { return; } // // Load the strong key file found in attributes when no // command line key was given // if (key_file != null || key_container != null) { LoadPublicKey(key_file, key_container); } else if (delay_sign) { Report.Warning(1607, 1, "Delay signing was requested but no key file was given"); } }
void Error_ObsoleteSecurityAttribute(Attribute a, string option) { Report.Warning(1699, 1, a.Location, "Use compiler option `{0}' or appropriate project settings instead of `{1}' attribute", option, a.Name); }
void Warning_ConstrainIsNotClsCompliant (Type t, Location loc, Report Report) { Report.SymbolRelatedToPreviousError (t); Report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant", TypeManager.CSharpName (t)); }
// // 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); }
private static XmlNode GetDocCommentNode(MemberCore mc, string name, Report Report) { // FIXME: It could be even optimizable as not // to use XmlDocument. But anyways the nodes // are not kept in memory. XmlDocument doc = RootContext.Documentation.XmlDocumentation; try { XmlElement el = doc.CreateElement ("member"); el.SetAttribute ("name", name); string normalized = mc.DocComment; el.InnerXml = normalized; // csc keeps lines as written in the sources // and inserts formatting indentation (which // is different from XmlTextWriter.Formatting // one), but when a start tag contains an // endline, it joins the next line. We don't // have to follow such a hacky behavior. string [] split = normalized.Split ('\n'); int j = 0; for (int i = 0; i < split.Length; i++) { string s = split [i].TrimEnd (); if (s.Length > 0) split [j++] = s; } el.InnerXml = line_head + String.Join ( line_head, split, 0, j); return el; } catch (Exception ex) { Report.Warning (1570, 1, mc.Location, "XML comment on `{0}' has non-well-formed XML ({1})", name, ex.Message); XmlComment com = doc.CreateComment (String.Format ("FIXME: Invalid documentation markup was found for member {0}", name)); return com; } }
public bool Define (DeclSpace parent, string method_full_name, Report Report) { TypeContainer container = parent.PartialContainer; PendingImplementation pending = container.PendingImplementations; MethodSpec ambig_iface_method; if (pending != null) { implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method); if (member.InterfaceType != null) { if (implementing == null) { if (member is PropertyBase) { Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'", method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType), member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.'))); } else { Report.Error (539, method.Location, "`{0}.{1}' in explicit interface declaration is not a member of interface", TypeManager.CSharpName (member.InterfaceType), member.ShortName); } return false; } if (implementing.IsAccessor && !method.IsAccessor) { Report.SymbolRelatedToPreviousError (implementing); Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor", member.GetSignatureForError (), TypeManager.CSharpSignature (implementing)); return false; } } else { if (implementing != null) { if (!method.IsAccessor) { if (implementing.IsAccessor) { Report.SymbolRelatedToPreviousError (implementing); Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}'", method.GetSignatureForError (), TypeManager.CSharpSignature (implementing)); } } else if (implementing.DeclaringType.IsInterface) { if (!implementing.IsAccessor) { Report.SymbolRelatedToPreviousError (implementing); Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation", method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ()); } else { PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod; if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) { Report.SymbolRelatedToPreviousError (implementing); Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'", method.GetSignatureForError (), implementing.GetSignatureForError ()); } } } } } } else { ambig_iface_method = null; } // // For implicit implementations, make sure we are public, for // explicit implementations, make sure we are private. // if (implementing != null){ // // Setting null inside this block will trigger a more // verbose error reporting for missing interface implementations // // The "candidate" function has been flagged already // but it wont get cleared // if (member.IsExplicitImpl){ if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) { Report.SymbolRelatedToPreviousError (implementing); Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier", method.GetSignatureForError ()); } if (ambig_iface_method != null) { Report.SymbolRelatedToPreviousError (ambig_iface_method); Report.SymbolRelatedToPreviousError (implementing); Report.Warning (473, 2, method.Location, "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead", method.GetSignatureForError ()); } } else { if (implementing.DeclaringType.IsInterface) { // // If this is an interface method implementation, // check for public accessibility // if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) { implementing = null; } } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){ // We may never be private. implementing = null; } else if ((modifiers & Modifiers.OVERRIDE) == 0){ // // We may be protected if we're overriding something. // implementing = null; } } // // Static is not allowed // if ((modifiers & Modifiers.STATIC) != 0){ implementing = null; } } // // If implementing is still valid, set flags // if (implementing != null){ // // When implementing interface methods, set NewSlot // unless, we are overwriting a method. // if (implementing.DeclaringType.IsInterface){ if ((modifiers & Modifiers.OVERRIDE) == 0) flags |= MethodAttributes.NewSlot; } flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig; // Set Final unless we're virtual, abstract or already overriding a method. if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0) flags |= MethodAttributes.Final; // // clear the pending implementation flag (requires explicit methods to be defined first) // parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName, member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method); // // Update indexer accessor name to match implementing abstract accessor // if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor) method_full_name = implementing.MemberDefinition.Name; } DefineMethodBuilder (container, method_full_name, method.ParameterInfo); if (builder == null) return false; // if (container.CurrentType != null) // declaring_type = container.CurrentType; // else declaring_type = container.Definition; if (implementing != null && member.IsExplicitImpl) { container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ()); } return true; }
// <summary> // This must be called before parsing/tokenizing any files. // </summary> static public void AddFile (Report r, string name) { string path = Path.GetFullPath (name); int id; if (source_files.TryGetValue (path, out id)){ string other_name = source_list [id - 1].Name; if (name.Equals (other_name)) r.Warning (2002, 1, "Source file `{0}' specified multiple times", other_name); else r.Warning (2002, 1, "Source filenames `{0}' and `{1}' both refer to the same file: {2}", name, other_name, path); return; } source_files.Add (path, ++source_count); CompilationUnit unit = new CompilationUnit (name, path, source_count); source_list.Add (unit); compile_units.Add (unit); }
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa) { Report Report = RootContext.ToplevelTypes.Compiler.Report; if (a.Type == pa.In && ModFlags == Modifier.OUT) { Report.Error(36, a.Location, "An out parameter cannot have the `In' attribute"); return; } if (a.Type == pa.ParamArray) { Report.Error(674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead"); return; } if (a.Type == PredefinedAttributes.Get.Out && (ModFlags & Modifier.REF) == Modifier.REF && !OptAttributes.Contains(pa.In)) { Report.Error(662, a.Location, "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither"); return; } if (a.Type == pa.CLSCompliant) { Report.Warning(3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead"); } if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) { Report.Error(1745, a.Location, "Cannot specify `{0}' attribute on optional parameter `{1}'", TypeManager.CSharpName(a.Type).Replace("Attribute", ""), Name); return; } if (a.Type == pa.DefaultParameterValue) { object val = a.GetParameterDefaultValue(); if (val != null) { Type t = val.GetType(); if (t.IsArray || TypeManager.IsSubclassOf(t, TypeManager.type_type)) { if (parameter_type == TypeManager.object_type) { if (!t.IsArray) { t = TypeManager.type_type; } Report.Error(1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute", TypeManager.CSharpName(t)); } else { Report.Error(1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'", TypeManager.CSharpName(parameter_type));; } return; } } if (parameter_type == TypeManager.object_type || (val == null && !TypeManager.IsGenericParameter(parameter_type) && TypeManager.IsReferenceType(parameter_type)) || (val != null && TypeManager.TypeToCoreType(val.GetType()) == parameter_type)) { builder.SetConstant(val); } else { Report.Error(1908, a.Location, "The type of the default value should match the type of the parameter"); } return; } base.ApplyAttributeBuilder(a, cb, pa); }
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]; }
void AddSourceFile (string fileName, List<CompilationSourceFile> sourceFiles) { string path = Path.GetFullPath (fileName); int index; if (source_file_index.TryGetValue (path, out index)) { string other_name = sourceFiles[index - 1].Name; if (fileName.Equals (other_name)) report.Warning (2002, 1, "Source file `{0}' specified multiple times", other_name); else report.Warning (2002, 1, "Source filenames `{0}' and `{1}' both refer to the same file: {2}", fileName, other_name, path); return; } var unit = new CompilationSourceFile (fileName, path, sourceFiles.Count + 1); sourceFiles.Add (unit); source_file_index.Add (path, unit.Index); }
public void VerifyClsCompliance (Report report) { foreach (var c in constraints) { if (c == null) continue; if (!c.Type.IsCLSCompliant ()) { report.SymbolRelatedToPreviousError (c.Type); report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant", c.Type.GetSignatureForError ()); } } }
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb) { if (a.Type == TypeManager.in_attribute_type && ModFlags == Modifier.OUT) { Report.Error(36, a.Location, "An out parameter cannot have the `In' attribute"); return; } if (a.Type == TypeManager.param_array_type) { Report.Error(674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead"); return; } if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) == Modifier.REF && TypeManager.in_attribute_type != null && !OptAttributes.Contains(TypeManager.in_attribute_type)) { Report.Error(662, a.Location, "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither"); return; } if (a.Type == TypeManager.cls_compliant_attribute_type) { Report.Warning(3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead"); } // TypeManager.default_parameter_value_attribute_type is null if !NET_2_0, or if System.dll is not referenced if (a.Type == TypeManager.default_parameter_value_attribute_type) { object val = a.GetParameterDefaultValue(); if (val != null) { Type t = val.GetType(); if (t.IsArray || TypeManager.IsSubclassOf(t, TypeManager.type_type)) { if (parameter_type == TypeManager.object_type) { if (!t.IsArray) { t = TypeManager.type_type; } Report.Error(1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultValue attribute", TypeManager.CSharpName(t)); } else { Report.Error(1909, a.Location, "The DefaultValue attribute is not applicable on parameters of type `{0}'", TypeManager.CSharpName(parameter_type));; } return; } } if (parameter_type == TypeManager.object_type || (val == null && !TypeManager.IsValueType(parameter_type)) || (val != null && TypeManager.TypeToCoreType(val.GetType()) == parameter_type)) { builder.SetConstant(val); } else { Report.Error(1908, a.Location, "The type of the default value should match the type of the parameter"); } return; } base.ApplyAttributeBuilder(a, cb); }
// // 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. // internal static void OnMethodGenerateDocComment( MethodCore mc, XmlElement el, Report Report) { var paramTags = new Dictionary<string, string> (); foreach (XmlElement pelem in el.SelectNodes ("param")) { string xname = pelem.GetAttribute ("name"); if (xname.Length == 0) continue; // really? but MS looks doing so if (xname != "" && mc.ParameterInfo.GetParameterIndexByName (xname) < 0) Report.Warning (1572, 2, mc.Location, "XML comment on `{0}' has a param tag for `{1}', but there is no parameter by that name", mc.GetSignatureForError (), xname); else if (paramTags.ContainsKey (xname)) Report.Warning (1571, 2, mc.Location, "XML comment on `{0}' has a duplicate param tag for `{1}'", mc.GetSignatureForError (), xname); paramTags [xname] = xname; } IParameterData [] plist = mc.ParameterInfo.FixedParameters; foreach (Parameter p in plist) { if (paramTags.Count > 0 && !paramTags.ContainsKey (p.Name)) Report.Warning (1573, 4, mc.Location, "Parameter `{0}' has no matching param tag in the XML comment for `{1}'", p.Name, mc.GetSignatureForError ()); } }
static void Report419(MemberCore mc, string member_name, MemberSpec [] mis, Report Report) { Report.Warning (419, 3, mc.Location, "Ambiguous reference in cref attribute `{0}'. Assuming `{1}' but other overloads including `{2}' have also matched", member_name, TypeManager.GetFullNameSignature (mis [0]), TypeManager.GetFullNameSignature (mis [1])); }
// // Processes "include" element. Check included file and // embed the document content inside this documentation node. // private static bool HandleInclude(MemberCore mc, XmlElement el, Report Report) { bool keep_include_node = false; string file = el.GetAttribute ("file"); string path = el.GetAttribute ("path"); if (file == "") { Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `file' attribute"); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el); keep_include_node = true; } else if (path.Length == 0) { Report.Warning (1590, 1, mc.Location, "Invalid XML `include' element. Missing `path' attribute"); el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el); keep_include_node = true; } else { XmlDocument doc; if (!RootContext.Documentation.StoredDocuments.TryGetValue (file, out doc)) { try { doc = new XmlDocument (); doc.Load (file); RootContext.Documentation.StoredDocuments.Add (file, doc); } catch (Exception) { el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (String.Format (" Badly formed XML in at comment file `{0}': cannot be included ", file)), el); Report.Warning (1592, 1, mc.Location, "Badly formed XML in included comments file -- `{0}'", file); } } if (doc != null) { try { XmlNodeList nl = doc.SelectNodes (path); if (nl.Count == 0) { el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" No matching elements were found for the include tag embedded here. "), el); keep_include_node = true; } foreach (XmlNode n in nl) el.ParentNode.InsertBefore (el.OwnerDocument.ImportNode (n, true), el); } catch (Exception ex) { el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Failed to insert some or all of included XML "), el); Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}' ({2})", path, file, ex.Message); } } } return keep_include_node; }
/// <summary> /// Cls compliance check whether methods or constructors parameters differing only in ref or out, or in array rank /// </summary> /// // TODO: refactor as method is always 'this' public static void VerifyClsParameterConflict (ArrayList al, MethodCore method, MemberInfo this_builder, Report Report) { EntryType tested_type = (method is Constructor ? EntryType.Constructor : EntryType.Method) | EntryType.Public; for (int i = 0; i < al.Count; ++i) { MemberCache.CacheEntry entry = (MemberCache.CacheEntry) al [i]; // skip itself if (entry.Member == this_builder) continue; if ((entry.EntryType & tested_type) != tested_type) continue; MethodBase method_to_compare = (MethodBase)entry.Member; AttributeTester.Result result = AttributeTester.AreOverloadedMethodParamsClsCompliant ( method.Parameters, TypeManager.GetParameterData (method_to_compare)); if (result == AttributeTester.Result.Ok) continue; IMethodData md = TypeManager.GetMethod (method_to_compare); // TODO: now we are ignoring CLSCompliance(false) on method from other assembly which is buggy. // However it is exactly what csc does. if (md != null && !md.IsClsComplianceRequired ()) continue; Report.SymbolRelatedToPreviousError (entry.Member); switch (result) { case AttributeTester.Result.RefOutArrayError: Report.Warning (3006, 1, method.Location, "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant", method.GetSignatureForError ()); continue; case AttributeTester.Result.ArrayArrayError: Report.Warning (3007, 1, method.Location, "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant", method.GetSignatureForError ()); continue; } throw new NotImplementedException (result.ToString ()); } }
private static void Normalize(MemberCore mc, ref string name, Report Report) { if (name.Length > 0 && name [0] == '@') name = name.Substring (1); else if (name == "this") name = "Item"; else if (Tokenizer.IsKeyword (name) && !IsTypeName (name)) Report.Warning (1041, 1, mc.Location, "Identifier expected. `{0}' is a keyword", name); }
// // 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 static string GetPackageFlags (string packages, Report report) { ProcessStartInfo pi = new ProcessStartInfo (); pi.FileName = "pkg-config"; pi.RedirectStandardOutput = true; pi.UseShellExecute = false; pi.Arguments = "--libs " + packages; Process p = null; try { p = Process.Start (pi); } catch (Exception e) { if (report == null) throw; report.Error (-27, "Couldn't run pkg-config: " + e.Message); return null; } if (p.StandardOutput == null) { if (report == null) throw new ApplicationException ("Specified package did not return any information"); report.Warning (-27, 1, "Specified package did not return any information"); p.Close (); return null; } string pkgout = p.StandardOutput.ReadToEnd (); p.WaitForExit (); if (p.ExitCode != 0) { if (report == null) throw new ApplicationException (pkgout); report.Error (-27, "Error running pkg-config. Check the above output."); p.Close (); return null; } p.Close (); return pkgout; }
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]); }
// // Processes "include" element. Check included file and // embed the document content inside this documentation node. // bool HandleInclude(MemberCore mc, XmlElement el) { bool keep_include_node = false; string file = el.GetAttribute("file"); string path = el.GetAttribute("path"); if (file == "") { Report.Warning(1590, 1, mc.Location, "Invalid XML `include' element. Missing `file' attribute"); el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" Include tag is invalid "), el); keep_include_node = true; } else if (path.Length == 0) { Report.Warning(1590, 1, mc.Location, "Invalid XML `include' element. Missing `path' attribute"); el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" Include tag is invalid "), el); keep_include_node = true; } else { XmlDocument doc; Exception exception = null; var full_path = Path.Combine(Path.GetDirectoryName(mc.Location.NameFullPath), file); if (!StoredDocuments.TryGetValue(full_path, out doc)) { try { doc = new XmlDocument(); doc.Load(full_path); StoredDocuments.Add(full_path, doc); } catch (Exception e) { exception = e; el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(String.Format(" Badly formed XML in at comment file `{0}': cannot be included ", file)), el); } } if (doc != null) { try { XmlNodeList nl = doc.SelectNodes(path); if (nl.Count == 0) { el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" No matching elements were found for the include tag embedded here. "), el); keep_include_node = true; } foreach (XmlNode n in nl) { el.ParentNode.InsertBefore(el.OwnerDocument.ImportNode(n, true), el); } } catch (Exception ex) { exception = ex; el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" Failed to insert some or all of included XML "), el); } } if (exception != null) { Report.Warning(1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}'. {2}", path, file, exception.Message); } } return(keep_include_node); }
// // 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()); } } }
public void WarningEnable (Location location, int code, Report Report) { if (!Report.CheckWarningCode (code, location)) return; if (Report.IsWarningDisabledGlobally (code)) Report.Warning (1635, 1, location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code); regions.Add (new Enable (location.Row, code)); }
// // 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); }
public void ApplyAttributeBuilder(Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.IsValidSecurityAttribute()) { a.ExtractSecurityPermissionSet(ctor, ref declarative_security); return; } if (a.Type == pa.AssemblyCulture) { string value = a.GetString(); if (value == null || value.Length == 0) { return; } if (Compiler.Settings.Target == Target.Exe) { a.Error_AttributeEmitError("The executables cannot be satelite assemblies, remove the attribute or keep it empty"); return; } if (value == "neutral") { value = ""; } if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetCulture(value, a.Location); } IsSatelliteAssembly = true; return; } if (a.Type == pa.AssemblyVersion) { string value = a.GetString(); if (value == null || value.Length == 0) { return; } var vinfo = IsValidAssemblyVersion(value, true); if (vinfo == null) { a.Error_AttributeEmitError(string.Format("Specified version `{0}' is not valid", value)); return; } if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetVersion(vinfo, a.Location); } return; } if (a.Type == pa.AssemblyAlgorithmId) { const int pos = 2; // skip CA header uint alg = (uint)cdata [pos]; alg |= ((uint)cdata [pos + 1]) << 8; alg |= ((uint)cdata [pos + 2]) << 16; alg |= ((uint)cdata [pos + 3]) << 24; if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetAlgorithmId(alg, a.Location); } return; } if (a.Type == pa.AssemblyFlags) { const int pos = 2; // skip CA header uint flags = (uint)cdata[pos]; flags |= ((uint)cdata [pos + 1]) << 8; flags |= ((uint)cdata [pos + 2]) << 16; flags |= ((uint)cdata [pos + 3]) << 24; // Ignore set PublicKey flag if assembly is not strongnamed if ((flags & (uint)AssemblyNameFlags.PublicKey) != 0 && public_key == null) { flags &= ~(uint)AssemblyNameFlags.PublicKey; } if (Compiler.Settings.Target == Target.Module) { SetCustomAttribute(ctor, cdata); } else { builder_extra.SetFlags(flags, a.Location); } return; } if (a.Type == pa.TypeForwarder) { TypeSpec t = a.GetArgumentType(); if (t == null || TypeManager.HasElementType(t)) { Report.Error(735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute"); return; } if (emitted_forwarders == null) { emitted_forwarders = new Dictionary <ITypeDefinition, Attribute> (); } else if (emitted_forwarders.ContainsKey(t.MemberDefinition)) { Report.SymbolRelatedToPreviousError(emitted_forwarders[t.MemberDefinition].Location, null); Report.Error(739, a.Location, "A duplicate type forward of type `{0}'", t.GetSignatureForError()); return; } emitted_forwarders.Add(t.MemberDefinition, a); if (t.MemberDefinition.DeclaringAssembly == this) { Report.SymbolRelatedToPreviousError(t); Report.Error(729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly", t.GetSignatureForError()); return; } if (t.IsNested) { Report.Error(730, a.Location, "Cannot forward type `{0}' because it is a nested type", t.GetSignatureForError()); return; } builder_extra.AddTypeForwarder(t.GetDefinition(), a.Location); return; } if (a.Type == pa.Extension) { a.Error_MisusedExtensionAttribute(); return; } if (a.Type == pa.InternalsVisibleTo) { string assembly_name = a.GetString(); if (assembly_name.Length == 0) { return; } #if STATIC ParsedAssemblyName aname; ParseAssemblyResult r = Fusion.ParseAssemblyName(assembly_name, out aname); if (r != ParseAssemblyResult.OK) { Report.Warning(1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved", assembly_name); return; } if (aname.Version != null || aname.Culture != null || aname.ProcessorArchitecture != ProcessorArchitecture.None) { Report.Error(1725, a.Location, "Friend assembly reference `{0}' is invalid. InternalsVisibleTo declarations cannot have a version, culture or processor architecture specified", assembly_name); return; } if (public_key != null && !aname.HasPublicKey) { Report.Error(1726, a.Location, "Friend assembly reference `{0}' is invalid. Strong named assemblies must specify a public key in their InternalsVisibleTo declarations", assembly_name); return; } #endif } else if (a.Type == pa.RuntimeCompatibility) { wrap_non_exception_throws_custom = true; } else if (a.Type == pa.AssemblyFileVersion) { string value = a.GetString(); if (string.IsNullOrEmpty(value) || IsValidAssemblyVersion(value, false) == null) { Report.Warning(1607, 1, a.Location, "The version number `{0}' specified for `{1}' is invalid", value, a.Name); return; } } SetCustomAttribute(ctor, cdata); }
/// <summary> /// Common method for Obsolete error/warning reporting. /// </summary> public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc, Report Report) { if (oa.IsError) { Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message); return; } if (oa.Message == null || oa.Message.Length == 0) { Report.Warning (612, 1, loc, "`{0}' is obsolete", member); return; } Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message); }
public void Warning_UselessOptionalParameter(Report Report) { Report.Warning(1066, 1, Location, "The default value specified for optional parameter `{0}' will never be used", Name); }
// // This parses the -arg and /arg options to the compiler, even if the strings // in the following text use "/arg" on the strings. // ParseResult ParseOption (string option, ref string[] args, CompilerSettings settings) { int idx = option.IndexOf (':'); string arg, value; if (idx == -1) { arg = option; value = ""; } else { arg = option.Substring (0, idx); value = option.Substring (idx + 1); } switch (arg.ToLowerInvariant ()) { case "/nologo": return ParseResult.Success; case "/t": case "/target": switch (value) { case "exe": settings.Target = Target.Exe; break; case "winexe": settings.Target = Target.WinExe; break; case "library": settings.Target = Target.Library; settings.TargetExt = ".dll"; break; case "module": settings.Target = Target.Module; settings.TargetExt = ".netmodule"; break; default: report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'"); return ParseResult.Error; } return ParseResult.Success; case "/out": if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } settings.OutputFile = value; return ParseResult.Success; case "/o": case "/o+": case "/optimize": case "/optimize+": settings.Optimize = true; return ParseResult.Success; case "/o-": case "/optimize-": settings.Optimize = false; return ParseResult.Success; // TODO: Not supported by csc 3.5+ case "/incremental": case "/incremental+": case "/incremental-": // nothing. return ParseResult.Success; case "/d": case "/define": { if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } foreach (string d in value.Split (argument_value_separator)) { string conditional = d.Trim (); if (!Tokenizer.IsValidIdentifier (conditional)) { report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional); continue; } RootContext.AddConditional (conditional); } return ParseResult.Success; } case "/bugreport": // // We should collect data, runtime, etc and store in the file specified // output.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs"); return ParseResult.Success; case "/pkg": { string packages; if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } packages = String.Join (" ", value.Split (new Char[] { ';', ',', '\n', '\r' })); string pkgout = null;// Driver.GetPackageFlags(packages, report); if (pkgout == null) return ParseResult.Error; string[] xargs = pkgout.Trim (new Char[] { ' ', '\n', '\r', '\t' }).Split (new Char[] { ' ', '\t' }); args = AddArgs (args, xargs); return ParseResult.Success; } case "/linkres": case "/linkresource": case "/res": case "/resource": AssemblyResource res = null; string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries); switch (s.Length) { case 1: if (s[0].Length == 0) goto default; res = new AssemblyResource (s[0], Path.GetFileName (s[0])); break; case 2: res = new AssemblyResource (s[0], s[1]); break; case 3: if (s[2] != "public" && s[2] != "private") { report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s[2]); return ParseResult.Error; } res = new AssemblyResource (s[0], s[1], s[2] == "private"); break; default: report.Error (-2005, "Wrong number of arguments for option `{0}'", option); return ParseResult.Error; } if (res != null) { res.IsEmbeded = arg[1] == 'r' || arg[1] == 'R'; AddResource (res, settings); } return ParseResult.Success; case "/recurse": if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } ProcessSourceFiles (value, true); return ParseResult.Success; case "/r": case "/reference": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } string[] refs = value.Split (argument_value_separator); foreach (string r in refs) { if (r.Length == 0) continue; string val = r; int index = val.IndexOf ('='); if (index > -1) { string alias = r.Substring (0, index); string assembly = r.Substring (index + 1); AddAssemblyReference (alias, assembly, settings); if (refs.Length != 1) { report.Error (2034, "Cannot specify multiple aliases using single /reference option"); return ParseResult.Error; } } else { settings.AssemblyReferences.Add (val); } } return ParseResult.Success; } case "/addmodule": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } string[] refs = value.Split (argument_value_separator); foreach (string r in refs) { settings.Modules.Add (r); } return ParseResult.Success; } case "/win32res": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } if (settings.Win32IconFile != null) report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time"); settings.Win32ResourceFile = value; return ParseResult.Success; } case "/win32icon": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } if (settings.Win32ResourceFile != null) report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time"); settings.Win32IconFile = value; return ParseResult.Success; } case "/doc": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } //settings.Documentation = new Documentation (value); return ParseResult.Error; } case "/lib": { string[] libdirs; if (value.Length == 0) { return ParseResult.Error; } libdirs = value.Split (argument_value_separator); foreach (string dir in libdirs) settings.ReferencesLookupPaths.Add (dir); return ParseResult.Success; } case "/debug-": settings.GenerateDebugInfo = false; return ParseResult.Success; case "/debug": if (value == "full" || value == "") settings.GenerateDebugInfo = true; return ParseResult.Success; case "/debug+": settings.GenerateDebugInfo = true; return ParseResult.Success; case "/checked": case "/checked+": settings.Checked = true; return ParseResult.Success; case "/checked-": settings.Checked = false; return ParseResult.Success; case "/clscheck": case "/clscheck+": settings.VerifyClsCompliance = true; return ParseResult.Success; case "/clscheck-": settings.VerifyClsCompliance = false; return ParseResult.Success; case "/unsafe": case "/unsafe+": settings.Unsafe = true; return ParseResult.Success; case "/unsafe-": settings.Unsafe = false; return ParseResult.Success; case "/warnaserror": case "/warnaserror+": if (value.Length == 0) { report.WarningsAreErrors = true; } else { foreach (string wid in value.Split (numeric_value_separator)) report.AddWarningAsError (wid); } return ParseResult.Success; case "/warnaserror-": if (value.Length == 0) { report.WarningsAreErrors = false; } else { foreach (string wid in value.Split (numeric_value_separator)) report.RemoveWarningAsError (wid); } return ParseResult.Success; case "/warn": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } SetWarningLevel (value); return ParseResult.Success; case "/nowarn": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } var warns = value.Split (numeric_value_separator); foreach (string wc in warns) { try { if (wc.Trim ().Length == 0) continue; int warn = Int32.Parse (wc); if (warn < 1) { throw new ArgumentOutOfRangeException ("warn"); } report.SetIgnoreWarning (warn); } catch { report.Error (1904, "`{0}' is not a valid warning number", wc); return ParseResult.Error; } } return ParseResult.Success; case "/noconfig": settings.LoadDefaultReferences = false; return ParseResult.Success; case "/platform": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } switch (value.ToLower (CultureInfo.InvariantCulture)) { case "anycpu": settings.Platform = Platform.AnyCPU; break; case "x86": settings.Platform = Platform.X86; break; case "x64": settings.Platform = Platform.X64; break; case "itanium": settings.Platform = Platform.IA64; break; default: report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'"); return ParseResult.Error; } return ParseResult.Success; case "/sdk": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } settings.SdkVersion = value; return ParseResult.Success; // We just ignore this. case "/errorreport": case "/filealign": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } return ParseResult.Success; case "/helpinternal": OtherFlags (); return ParseResult.Stop; case "/help": case "/?": Usage (); return ParseResult.Stop; case "/main": case "/m": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } settings.MainClass = value; return ParseResult.Success; case "/nostdlib": case "/nostdlib+": settings.StdLib = false; return ParseResult.Success; case "/nostdlib-": settings.StdLib = true; return ParseResult.Success; case "/fullpaths": report.Printer.ShowFullPaths = true; return ParseResult.Success; case "/keyfile": if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } settings.StrongNameKeyFile = value; return ParseResult.Success; case "/keycontainer": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } settings.StrongNameKeyContainer = value; return ParseResult.Success; case "/delaysign+": case "/delaysign": settings.StrongNameDelaySign = true; return ParseResult.Success; case "/delaysign-": settings.StrongNameDelaySign = false; return ParseResult.Success; case "/langversion": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } switch (value.ToLowerInvariant ()) { case "iso-1": settings.Version = LanguageVersion.ISO_1; return ParseResult.Success; case "default": settings.Version = LanguageVersion.Default; RootContext.AddConditional ("__V2__"); return ParseResult.Success; case "iso-2": settings.Version = LanguageVersion.ISO_2; return ParseResult.Success; case "3": settings.Version = LanguageVersion.V_3; return ParseResult.Success; case "future": settings.Version = LanguageVersion.Future; return ParseResult.Success; } report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3' or `Default'", value); return ParseResult.Error; case "/codepage": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } switch (value) { case "utf8": settings.Encoding = new UTF8Encoding (); break; case "reset": settings.Encoding = new UTF8Encoding ();//Encoding.Default; break; default: try { settings.Encoding = new UTF8Encoding(); //Encoding.GetEncoding(int.Parse(value)); } catch { report.Error (2016, "Code page `{0}' is invalid or not installed", value); } return ParseResult.Error; } return ParseResult.Success; default: return ParseResult.UnknownOption; } }
public void Warning_UselessOptionalParameter (Report Report) { Report.Warning (1066, 1, Location, "The default value specified for optional parameter `{0}' will never be used", Name); }
// // 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> /// The main virtual method for CLS-Compliant verifications. /// The method returns true if member is CLS-Compliant and false if member is not /// CLS-Compliant which means that CLS-Compliant tests are not necessary. A descendants override it /// and add their extra verifications. /// </summary> protected virtual bool VerifyClsCompliance() { if (HasClsCompliantAttribute) { if (!Module.DeclaringAssembly.HasCLSCompliantAttribute) { Attribute a = OptAttributes.Search(Module.PredefinedAttributes.CLSCompliant); if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) { Report.Warning(3021, 2, a.Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", GetSignatureForError()); } else { Report.Warning(3014, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant", GetSignatureForError()); } return(false); } if (!IsExposedFromAssembly()) { Attribute a = OptAttributes.Search(Module.PredefinedAttributes.CLSCompliant); Report.Warning(3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError()); return(false); } if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) { if (Parent is Interface && Parent.IsClsComplianceRequired()) { Report.Warning(3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError()); } else if (Parent.Kind == MemberKind.Class && (ModFlags & Modifiers.ABSTRACT) != 0 && Parent.IsClsComplianceRequired()) { Report.Warning(3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError()); } return(false); } if (Parent.Kind != MemberKind.Namespace && Parent.Kind != 0 && !Parent.IsClsComplianceRequired()) { Attribute a = OptAttributes.Search(Module.PredefinedAttributes.CLSCompliant); Report.Warning(3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'", GetSignatureForError(), Parent.GetSignatureForError()); return(false); } } else { if (!IsExposedFromAssembly()) { return(false); } if (!Parent.IsClsComplianceRequired()) { return(false); } } if (member_name.Name[0] == '_') { Warning_IdentifierNotCompliant(); } if (member_name.TypeParameters != null) { member_name.TypeParameters.VerifyClsCompliance(); } return(true); }
// TODO: rewrite this code (to kill N bugs and make it faster) and use standard ApplyAttribute way. public AssemblyName GetAssemblyName(string name, string output) { if (OptAttributes != null) { foreach (Attribute a in OptAttributes.Attrs) { // cannot rely on any resolve-based members before you call Resolve if (a.ExplicitTarget == null || a.ExplicitTarget != "assembly") { continue; } // TODO: This code is buggy: comparing Attribute name without resolving is wrong. // However, this is invoked by CodeGen.Init, when none of the namespaces // are loaded yet. // TODO: Does not handle quoted attributes properly switch (a.Name) { case "AssemblyKeyFile": case "AssemblyKeyFileAttribute": case "System.Reflection.AssemblyKeyFileAttribute": if (RootContext.StrongNameKeyFile != null) { Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError()); Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", "keyfile", "System.Reflection.AssemblyKeyFileAttribute"); } else { string value = a.GetString(); if (value != null && value.Length != 0) { RootContext.StrongNameKeyFile = value; } } break; case "AssemblyKeyName": case "AssemblyKeyNameAttribute": case "System.Reflection.AssemblyKeyNameAttribute": if (RootContext.StrongNameKeyContainer != null) { Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError()); Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module", "keycontainer", "System.Reflection.AssemblyKeyNameAttribute"); } else { string value = a.GetString(); if (value != null && value.Length != 0) { RootContext.StrongNameKeyContainer = value; } } break; case "AssemblyDelaySign": case "AssemblyDelaySignAttribute": case "System.Reflection.AssemblyDelaySignAttribute": RootContext.StrongNameDelaySign = a.GetBoolean(); break; } } } AssemblyName an = new AssemblyName(); an.Name = Path.GetFileNameWithoutExtension(name); // note: delay doesn't apply when using a key container if (RootContext.StrongNameKeyContainer != null) { an.KeyPair = new StrongNameKeyPair(RootContext.StrongNameKeyContainer); return(an); } // strongname is optional if (RootContext.StrongNameKeyFile == null) { return(an); } string AssemblyDir = Path.GetDirectoryName(output); // the StrongName key file may be relative to (a) the compiled // file or (b) to the output assembly. See bugzilla #55320 // http://bugzilla.ximian.com/show_bug.cgi?id=55320 // (a) relative to the compiled file string filename = Path.GetFullPath(RootContext.StrongNameKeyFile); bool exist = File.Exists(filename); if ((!exist) && (AssemblyDir != null) && (AssemblyDir != String.Empty)) { // (b) relative to the outputed assembly filename = Path.GetFullPath(Path.Combine(AssemblyDir, RootContext.StrongNameKeyFile)); exist = File.Exists(filename); } if (exist) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { byte[] snkeypair = new byte [fs.Length]; fs.Read(snkeypair, 0, snkeypair.Length); if (RootContext.StrongNameDelaySign) { // delayed signing - DO NOT include private key SetPublicKey(an, snkeypair); } else { // no delay so we make sure we have the private key try { CryptoConvert.FromCapiPrivateKeyBlob(snkeypair); an.KeyPair = new StrongNameKeyPair(snkeypair); } catch (CryptographicException) { if (snkeypair.Length == 16) { // error # is different for ECMA key Report.Error(1606, "Could not sign the assembly. " + "ECMA key can only be used to delay-sign assemblies"); } else { Error_AssemblySigning("The specified file `" + RootContext.StrongNameKeyFile + "' does not have a private key"); } return(null); } } } } else { Error_AssemblySigning("The specified file `" + RootContext.StrongNameKeyFile + "' does not exist"); return(null); } return(an); }