// TODO: merge method and mb public ReturnParameter (MemberCore method, MethodBuilder mb, Location location) { this.method = method; try { builder = mb.DefineParameter (0, ParameterAttributes.None, ""); } catch (ArgumentOutOfRangeException) { method.Compiler.Report.RuntimeMissingSupport (location, "custom attributes on the return type"); } }
public override bool EnableOverloadChecks (MemberCore overload) { if (overload is Indexer) { caching_flags |= Flags.MethodOverloadsExist; return true; } return base.EnableOverloadChecks (overload); }
public override bool EnableOverloadChecks (MemberCore overload) { if (overload is MethodCore) { caching_flags |= Flags.MethodOverloadsExist; return true; } // This can only happen with indexers and it will // be catched as indexer difference if (overload is AbstractPropertyEventMethod) return true; return false; }
public override bool EnableOverloadChecks (MemberCore overload) { if (overload is Indexer) return false; return base.EnableOverloadChecks (overload); }
/// <summary> /// Returns true when a member supports multiple overloads (methods, indexers, etc) /// </summary> public virtual bool EnableOverloadChecks(MemberCore overload) { return(false); }
public virtual void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression) { if (IsPartialPart) PartialContainer.RegisterFieldForInitialization (field, expression); if ((field.ModFlags & Modifiers.STATIC) != 0){ if (initialized_static_fields == null) { HasStaticFieldInitializer = true; initialized_static_fields = new List<FieldInitializer> (4); } initialized_static_fields.Add (expression); } else { if (initialized_fields == null) initialized_fields = new List<FieldInitializer> (4); initialized_fields.Add (expression); } }
// // Adds the member to defined_names table. It tests for duplications and enclosing name conflicts // public virtual void AddNameToContainer (MemberCore symbol, string name) { if (((ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0) return; MemberCore mc; if (!PartialContainer.defined_names.TryGetValue (name, out mc)) { PartialContainer.defined_names.Add (name, symbol); return; } if (symbol.EnableOverloadChecks (mc)) return; InterfaceMemberBase im = mc as InterfaceMemberBase; if (im != null && im.IsExplicitImpl) return; Report.SymbolRelatedToPreviousError (mc); if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) { Error_MissingPartialModifier (symbol); return; } if (symbol is TypeParameter) { Report.Error (692, symbol.Location, "Duplicate type parameter `{0}'", symbol.GetSignatureForError ()); } else { Report.Error (102, symbol.Location, "The type `{0}' already contains a definition for `{1}'", GetSignatureForError (), name); } return; }
public InternalErrorException (MemberCore mc, Exception e) : base (mc.Location + " " + mc.GetSignatureForError (), e) { }
public InternalErrorException(MemberCore mc, Exception e) : base(mc.Location + " " + mc.GetSignatureForError(), e) { }
public DocumentationMemberContext(MemberCore host, MemberName contextName) { this.host = host; this.contextName = contextName; }
// // 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); }
// // Handles <exception> elements. // void HandleException(MemberCore mc, TypeContainer ds, XmlElement seealso) { HandleXrefCommon(mc, ds, seealso); }
// // Handles <see> elements. // void HandleSee(MemberCore mc, TypeContainer ds, XmlElement see) { HandleXrefCommon(mc, ds, see); }
// // 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 void GenerateDocumentationForMember(MemberCore mc) { string name = mc.DocCommentHeader + mc.GetSignatureForDocumentation(); XmlNode n = GetDocCommentNode(mc, name); XmlElement el = n as XmlElement; if (el != null) { var pm = mc as IParametersMember; if (pm != null) { CheckParametersComments(mc, pm, el); } // FIXME: it could be done with XmlReader XmlNodeList nl = n.SelectNodes(".//include"); if (nl.Count > 0) { // It could result in current node removal, so prepare another list to iterate. var al = new List <XmlNode> (nl.Count); foreach (XmlNode inc in nl) { al.Add(inc); } foreach (XmlElement inc in al) { if (!HandleInclude(mc, inc)) { inc.ParentNode.RemoveChild(inc); } } } // FIXME: it could be done with XmlReader var ds_target = mc as TypeContainer; if (ds_target == null) { ds_target = mc.Parent; } foreach (XmlElement see in n.SelectNodes(".//see")) { HandleSee(mc, ds_target, see); } foreach (XmlElement seealso in n.SelectNodes(".//seealso")) { HandleSeeAlso(mc, ds_target, seealso); } foreach (XmlElement see in n.SelectNodes(".//exception")) { HandleException(mc, ds_target, see); } foreach (XmlElement node in n.SelectNodes(".//typeparam")) { HandleTypeParam(mc, node); } foreach (XmlElement node in n.SelectNodes(".//typeparamref")) { HandleTypeParamRef(mc, node); } } n.WriteTo(XmlCommentOutput); }
public override void Visit (MemberCore member) { Console.WriteLine ("Unknown member:"); Console.WriteLine (member.GetType () + "-> Member {0}", member.GetSignatureForError ()); }
public void ResolveDefaultValues (MemberCore m) { ResolveContext rc = null; for (int i = 0; i < parameters.Length; ++i) { Parameter p = (Parameter) parameters [i]; // // Try not to enter default values resolution if there are is not any default value possible // if (p.HasDefaultValue || p.OptAttributes != null) { if (rc == null) rc = new ResolveContext (m); p.ResolveDefaultValue (rc); } } }
public void SymbolRelatedToPreviousError(MemberCore mc) { SymbolRelatedToPreviousError(mc.Location, mc.GetSignatureForError()); }
public void ReplaceMember (MemberCore oldsymbol, MemberCore newsymbol) { var i = members.IndexOf (oldsymbol); if (i == -1) throw new InvalidOperationException("No member to replace"); members[i] = newsymbol; ReplaceNameInContainer (newsymbol, newsymbol.MemberName.Basename); }
public virtual void Visit(MemberCore member) { Debug.Fail("unknown member type: " + member.GetType()); }
// // Replaces the member in the defined_names table. // public virtual void ReplaceNameInContainer (MemberCore newsymbol, string name) { if (((ModFlags | newsymbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0) return; MemberCore mc; if (PartialContainer.defined_names.TryGetValue (name, out mc)) { PartialContainer.defined_names[name] = newsymbol; } }
// // Performs the validation on a Method's modifiers (properties have // the same properties). // // TODO: Why is it not done at parse stage, move to Modifiers::Check // public bool MethodModifiersValid (MemberCore mc) { const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE); const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL); bool ok = true; var flags = mc.ModFlags; // // At most one of static, virtual or override // if ((flags & Modifiers.STATIC) != 0){ if ((flags & vao) != 0){ Report.Error (112, mc.Location, "A static member `{0}' cannot be marked as override, virtual or abstract", mc.GetSignatureForError ()); ok = false; } } if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){ Report.Error (113, mc.Location, "A member `{0}' marked as override cannot be marked as new or virtual", mc.GetSignatureForError ()); ok = false; } // // If the declaration includes the abstract modifier, then the // declaration does not include static, virtual or extern // if ((flags & Modifiers.ABSTRACT) != 0){ if ((flags & Modifiers.EXTERN) != 0){ Report.Error ( 180, mc.Location, "`{0}' cannot be both extern and abstract", mc.GetSignatureForError ()); ok = false; } if ((flags & Modifiers.SEALED) != 0) { Report.Error (502, mc.Location, "`{0}' cannot be both abstract and sealed", mc.GetSignatureForError ()); ok = false; } if ((flags & Modifiers.VIRTUAL) != 0){ Report.Error (503, mc.Location, "The abstract method `{0}' cannot be marked virtual", mc.GetSignatureForError ()); ok = false; } if ((ModFlags & Modifiers.ABSTRACT) == 0){ Report.SymbolRelatedToPreviousError (this); Report.Error (513, mc.Location, "`{0}' is abstract but it is declared in the non-abstract class `{1}'", mc.GetSignatureForError (), GetSignatureForError ()); ok = false; } } if ((flags & Modifiers.PRIVATE) != 0){ if ((flags & vao) != 0){ Report.Error (621, mc.Location, "`{0}': virtual or abstract members cannot be private", mc.GetSignatureForError ()); ok = false; } } if ((flags & Modifiers.SEALED) != 0){ if ((flags & Modifiers.OVERRIDE) == 0){ Report.Error (238, mc.Location, "`{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ()); ok = false; } } return ok; }
// // Checks whether the type P is as accessible as this member // public bool IsAccessibleAs(TypeSpec p) { // // if M is private, its accessibility is the same as this declspace. // we already know that P is accessible to T before this method, so we // may return true. // if ((mod_flags & Modifiers.PRIVATE) != 0) { return(true); } while (TypeManager.HasElementType(p)) { p = TypeManager.GetElementType(p); } if (p.IsGenericParameter) { return(true); } for (TypeSpec p_parent; p != null; p = p_parent) { p_parent = p.DeclaringType; if (p.IsGeneric) { foreach (TypeSpec t in p.TypeArguments) { if (!IsAccessibleAs(t)) { return(false); } } } var pAccess = p.Modifiers & Modifiers.AccessibilityMask; if (pAccess == Modifiers.PUBLIC) { continue; } bool same_access_restrictions = false; for (MemberCore mc = this; !same_access_restrictions && mc != null && mc.Parent != null; mc = mc.Parent) { var al = mc.ModFlags & Modifiers.AccessibilityMask; switch (pAccess) { case Modifiers.INTERNAL: if (al == Modifiers.PRIVATE || al == Modifiers.INTERNAL) { same_access_restrictions = p.MemberDefinition.IsInternalAsPublic(mc.Module.DeclaringAssembly); } break; case Modifiers.PROTECTED: if (al == Modifiers.PROTECTED) { same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition(p_parent); break; } if (al == Modifiers.PRIVATE) { // // When type is private and any of its parents derives from // protected type then the type is accessible // while (mc.Parent != null && mc.Parent.PartialContainer != null) { if (mc.Parent.PartialContainer.IsBaseTypeDefinition(p_parent)) { same_access_restrictions = true; } mc = mc.Parent; } } break; case Modifiers.PROTECTED | Modifiers.INTERNAL: if (al == Modifiers.INTERNAL) { same_access_restrictions = p.MemberDefinition.IsInternalAsPublic(mc.Module.DeclaringAssembly); } else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL)) { same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition(p_parent) && p.MemberDefinition.IsInternalAsPublic(mc.Module.DeclaringAssembly); } else { goto case Modifiers.PROTECTED; } break; case Modifiers.PRIVATE: // // Both are private and share same parent // if (al == Modifiers.PRIVATE) { var decl = mc.Parent; do { same_access_restrictions = decl.CurrentType.MemberDefinition == p_parent.MemberDefinition; } while (!same_access_restrictions && !decl.PartialContainer.IsTopLevel && (decl = decl.Parent) != null); } break; default: throw new InternalErrorException(al.ToString()); } } if (!same_access_restrictions) { return(false); } } return(true); }
public override void AddNameToContainer (MemberCore symbol, string name) { if (!(symbol is Constructor) && symbol.MemberName.Name == MemberName.Name) { if (symbol is TypeParameter) { Report.Error (694, symbol.Location, "Type parameter `{0}' has same name as containing type, or method", symbol.GetSignatureForError ()); return; } InterfaceMemberBase imb = symbol as InterfaceMemberBase; if (imb == null || !imb.IsExplicitImpl) { Report.SymbolRelatedToPreviousError (this); Report.Error (542, symbol.Location, "`{0}': member names cannot be the same as their enclosing type", symbol.GetSignatureForError ()); return; } } base.AddNameToContainer (symbol, name); }
public void AppendToMember(MemberCore existing, params Location[] locations) { AppendToMember(existing, (IEnumerable <Location>)locations); }
public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression) { if ((field.ModFlags & Modifiers.STATIC) == 0) { Report.Error (573, field.Location, "`{0}': Structs cannot have instance field initializers", field.GetSignatureForError ()); return; } base.RegisterFieldForInitialization (field, expression); }
public override bool EnableOverloadChecks (MemberCore overload) { if (overload is MethodCore) { caching_flags |= Flags.MethodOverloadsExist; return true; } if (overload is AbstractPropertyEventMethod) return true; return base.EnableOverloadChecks (overload); }
protected void Error_MissingPartialModifier (MemberCore type) { Report.Error (260, type.Location, "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists", type.GetSignatureForError ()); }
/// <summary> /// Returns true when a member supports multiple overloads (methods, indexers, etc) /// </summary> public virtual bool EnableOverloadChecks (MemberCore overload) { return false; }
protected static bool CheckAccessModifiers (MemberCore this_member, MemberSpec base_member) { var thisp = this_member.ModFlags & Modifiers.AccessibilityMask; var base_classp = base_member.Modifiers & Modifiers.AccessibilityMask; if ((base_classp & (Modifiers.PROTECTED | Modifiers.INTERNAL)) == (Modifiers.PROTECTED | Modifiers.INTERNAL)) { // // It must be at least "protected" // if ((thisp & Modifiers.PROTECTED) == 0) { return false; } // // when overriding protected internal, the method can be declared // protected internal only within the same assembly or assembly // which has InternalsVisibleTo // if ((thisp & Modifiers.INTERNAL) != 0) { return base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly); } // // protected overriding protected internal inside same assembly // requires internal modifier as well // if (base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (this_member.Module.DeclaringAssembly)) { return false; } return true; } return thisp == base_classp; }
public virtual void Visit (MemberCore member) { Debug.Fail ("unknown member type: " + member.GetType ()); }
public override bool EnableOverloadChecks (MemberCore overload) { // // Two members can differ in their explicit interface // type parameter only // InterfaceMemberBase imb = overload as InterfaceMemberBase; if (imb != null && imb.IsExplicitImpl) { if (IsExplicitImpl) { caching_flags |= Flags.MethodOverloadsExist; } return true; } return IsExplicitImpl; }
// // Parameters checks for members which don't have a block // public void CheckParameters (MemberCore member) { for (int i = 0; i < parameters.Length; ++i) { var name = parameters[i].Name; for (int ii = i + 1; ii < parameters.Length; ++ii) { if (parameters[ii].Name == name) this[ii].Error_DuplicateName (member.Compiler.Report); } } }
protected void Error_CannotChangeAccessModifiers (MemberCore member, MemberSpec base_member) { var base_modifiers = base_member.Modifiers; // Remove internal modifier from types which are not internally accessible if ((base_modifiers & Modifiers.AccessibilityMask) == (Modifiers.PROTECTED | Modifiers.INTERNAL) && !base_member.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly)) base_modifiers = Modifiers.PROTECTED; Report.SymbolRelatedToPreviousError (base_member); Report.Error (507, member.Location, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'", member.GetSignatureForError (), ModifiersExtensions.AccessibilityName (base_modifiers), base_member.GetSignatureForError ()); }
public void AddMember (MemberCore symbol) { if (symbol.MemberName.ExplicitInterface != null) { if (!(Kind == MemberKind.Class || Kind == MemberKind.Struct)) { Report.Error (541, symbol.Location, "`{0}': explicit interface declaration can only be declared in a class or struct", symbol.GetSignatureForError ()); } } AddNameToContainer (symbol, symbol.MemberName.Basename); members.Add (symbol); }
public void SymbolRelatedToPreviousError (MemberCore mc) { SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ()); }