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); }
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))); } }
// // 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 void Warning_UselessOptionalParameter (Report Report) { Report.Warning (1066, 1, Location, "The default value specified for optional parameter `{0}' will never be used", Name); }
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"); } }
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}'", TypeManager.CSharpName(t)); 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", TypeManager.CSharpName(t)); return; } if (t.IsNested) { Report.Error(730, a.Location, "Cannot forward type `{0}' because it is a nested type", TypeManager.CSharpName(t)); 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); }
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); }
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; }
protected void Warning_IdentifierNotCompliant() { Report.Warning(3008, 1, MemberName.Location, "Identifier `{0}' is not CLS-compliant", 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); }
// // 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)); 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 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()); 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); }
// // 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); }