protected void AddPartial (TypeDefinition next_part, TypeDefinition existing) { next_part.ModFlags |= Modifiers.PARTIAL; if (existing == null) { AddTypeContainer (next_part); return; } if ((existing.ModFlags & Modifiers.PARTIAL) == 0) { if (existing.Kind != next_part.Kind) { AddTypeContainer (next_part); } else { Report.SymbolRelatedToPreviousError (next_part); Error_MissingPartialModifier (existing); } return; } if (existing.Kind != next_part.Kind) { Report.SymbolRelatedToPreviousError (existing); Report.Error (261, next_part.Location, "Partial declarations of `{0}' must be all classes, all structs or all interfaces", next_part.GetSignatureForError ()); } if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) && ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) == 0 && (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) == 0)) { Report.SymbolRelatedToPreviousError (existing); Report.Error (262, next_part.Location, "Partial declarations of `{0}' have conflicting accessibility modifiers", next_part.GetSignatureForError ()); } var tc_names = existing.CurrentTypeParameters; if (tc_names != null) { for (int i = 0; i < tc_names.Count; ++i) { var tp = next_part.MemberName.TypeParameters[i]; if (tc_names[i].MemberName.Name != tp.MemberName.Name) { Report.SymbolRelatedToPreviousError (existing.Location, ""); Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order", next_part.GetSignatureForError ()); break; } if (tc_names[i].Variance != tp.Variance) { Report.SymbolRelatedToPreviousError (existing.Location, ""); Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers", next_part.GetSignatureForError ()); break; } } } if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0) { existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFIER | Modifiers.AccessibilityMask); } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFIER) != 0) { existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFIER | Modifiers.AccessibilityMask); existing.ModFlags |= next_part.ModFlags; } else { existing.ModFlags |= next_part.ModFlags; } existing.Definition.Modifiers = existing.ModFlags; if (next_part.attributes != null) { if (existing.attributes == null) existing.attributes = next_part.attributes; else existing.attributes.AddAttributes (next_part.attributes.Attrs); } next_part.PartialContainer = existing; existing.AddPartialPart (next_part); AddTypeContainerMember (next_part); }
public bool Define (TypeDefinition container, string method_full_name) { PendingImplementation pending = container.PendingImplementations; MethodSpec ambig_iface_method; bool optional = false; if (pending != null) { implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method, ref optional); if (member.InterfaceType != null) { if (implementing == null) { if (member is PropertyBase) { container.Compiler.Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'", method.GetSignatureForError (), member.InterfaceType.GetSignatureForError (), member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.'))); } else { container.Compiler.Report.Error (539, method.Location, "`{0}.{1}' in explicit interface declaration is not a member of interface", member.InterfaceType.GetSignatureForError (), member.ShortName); } return false; } if (implementing.IsAccessor && !method.IsAccessor) { container.Compiler.Report.SymbolRelatedToPreviousError (implementing); container.Compiler.Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor", member.GetSignatureForError (), implementing.GetSignatureForError ()); return false; } } else { if (implementing != null && !optional) { if (!method.IsAccessor) { if (implementing.IsAccessor) { container.Compiler.Report.SymbolRelatedToPreviousError (implementing); container.Compiler.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) { container.Compiler.Report.SymbolRelatedToPreviousError (implementing); container.Compiler.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) { container.Compiler.Report.SymbolRelatedToPreviousError (implementing); container.Compiler.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){ if (member.IsExplicitImpl) { if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) { container.Compiler.Report.SymbolRelatedToPreviousError (implementing); container.Compiler.Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier", method.GetSignatureForError ()); } if (ambig_iface_method != null) { container.Compiler.Report.SymbolRelatedToPreviousError (ambig_iface_method); container.Compiler.Report.SymbolRelatedToPreviousError (implementing); container.Compiler.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 { // // Setting implementin to null inside this block will trigger a more // verbose error reporting for missing interface implementations // 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 (optional && (container.Interfaces == null || !container.Definition.Interfaces.Contains (implementing.DeclaringType))) { // // We are not implementing interface when base class already implemented it // 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 ((modifiers & Modifiers.OVERRIDE) == 0 && implementing.DeclaringType.IsInterface) { 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) // pending.ImplementMethod (method.MethodName, member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method, ref optional); // // Update indexer accessor name to match implementing abstract accessor // if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor) method_full_name = implementing.MemberDefinition.Name; } full_name = method_full_name; declaring_type = container.Definition; return true; }