return tc.GetSignatureForError ();
}
- public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
+ public IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
{
return null;
}
// Holds the compiler generated classes
List<CompilerGeneratedClass> compiler_generated;
+ Dictionary<MethodSpec, Method> hoisted_base_call_proxies;
+
//
// Pointers to the default constructor and the default static constructor
//
return AddToContainer (symbol, symbol.MemberName.Basename);
}
+ public bool AddMember (MemberCore symbol, string name)
+ {
+ return AddToContainer (symbol, name);
+ }
+
protected virtual bool AddMemberType (TypeContainer ds)
{
return AddToContainer (ds, ds.Basename);
if (fne_resolved.Type.IsInterface) {
for (int ii = 0; ii < j; ++ii) {
- if (TypeManager.IsEqual (fne_resolved.Type, ifaces [ii].Type)) {
+ if (fne_resolved.Type == ifaces [ii].Type) {
Report.Error (528, Location, "`{0}' is already listed in interface list",
fne_resolved.GetSignatureForError ());
break;
if (o_b == null || o_b.OperatorType != matching_type)
continue;
- if (!TypeManager.IsEqual (o_a.ReturnType, o_b.ReturnType))
+ if (!TypeSpecComparer.IsEqual (o_a.ReturnType, o_b.ReturnType))
continue;
- if (!TypeSpecComparer.Default.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
+ if (!TypeSpecComparer.Equals (o_a.ParameterTypes, o_b.ParameterTypes))
continue;
operators[i] = null;
return true;
}
+ //
+ // Creates a proxy base method call inside this container for hoisted base member calls
+ //
+ public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
+ {
+ Method proxy_method;
+
+ //
+ // One proxy per base method is enough
+ //
+ if (hoisted_base_call_proxies == null) {
+ hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
+ proxy_method = null;
+ } else {
+ hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
+ }
+
+ if (proxy_method == null) {
+ string name = CompilerGeneratedClass.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
+ var cloned_params = ParametersCompiled.CreateFullyResolved (method.Parameters.FixedParameters, method.Parameters.Types);
+ if (method.Parameters.HasArglist) {
+ cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
+ cloned_params.Types[0] = TypeManager.runtime_argument_handle_type;
+ }
+
+ GenericMethod generic_method;
+ MemberName member_name;
+ if (method.IsGeneric) {
+ //
+ // Copy all base generic method type parameters info
+ //
+ var hoisted_tparams = method.GenericDefinition.TypeParameters;
+ var targs = new TypeArguments ();
+ var type_params = new TypeParameter[hoisted_tparams.Length];
+ for (int i = 0; i < type_params.Length; ++i) {
+ var tp = hoisted_tparams[i];
+ targs.Add (new TypeParameterName (tp.Name, null, Location));
+ type_params[i] = new TypeParameter (tp, null, null, new MemberName (tp.Name), null);
+ }
+
+ member_name = new MemberName (name, targs, Location);
+ generic_method = new GenericMethod (NamespaceEntry, this, member_name, type_params,
+ new TypeExpression (method.ReturnType, Location), cloned_params);
+ } else {
+ member_name = new MemberName (name);
+ generic_method = null;
+ }
+
+ // Compiler generated proxy
+ proxy_method = new Method (this, generic_method, new TypeExpression (method.ReturnType, Location),
+ Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
+ member_name, cloned_params, null);
+
+ var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location);
+
+ var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
+ mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
+
+ // Get all the method parameters and pass them as arguments
+ var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
+ Statement statement;
+ if (method.ReturnType == TypeManager.void_type)
+ statement = new StatementExpression (real_base_call);
+ else
+ statement = new Return (real_base_call, Location);
+
+ block.AddStatement (statement);
+ proxy_method.Block = block;
+
+ methods.Add (proxy_method);
+ proxy_method.Define ();
+
+ hoisted_base_call_proxies.Add (method, proxy_method);
+ }
+
+ return proxy_method.Spec;
+ }
+
bool DefineBaseTypes ()
{
iface_exprs = ResolveBaseTypes (out base_type_expr);
protected virtual void DefineContainerMembers (System.Collections.IList mcal) // IList<MemberCore>
{
if (mcal != null) {
- foreach (MemberCore mc in mcal) {
+ for (int i = 0; i < mcal.Count; ++i) {
+ MemberCore mc = (MemberCore) mcal[i];
try {
mc.Define ();
} catch (Exception e) {
// Performs the validation on a Method's modifiers (properties have
// the same properties).
//
+ // TODO: Why is it not done at parse stage ?
+ //
public bool MethodModifiersValid (MemberCore mc)
{
const Modifiers vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
- const Modifiers va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
const Modifiers nv = (Modifiers.NEW | Modifiers.VIRTUAL);
bool ok = true;
var flags = mc.ModFlags;
}
}
- if (Kind == MemberKind.Struct){
- if ((flags & va) != 0){
- ModifiersExtensions.Error_InvalidModifier (mc.Location, "virtual or abstract", Report);
- 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 ());
var ifaces = spec.Interfaces;
if (ifaces != null) {
foreach (TypeSpec t in ifaces){
- if (TypeManager.IsEqual (t, mb.InterfaceType))
+ if (t == mb.InterfaceType)
return true;
}
}
protected override bool AddToContainer (MemberCore symbol, string name)
{
- if (name == MemberName.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 false;
}
-
+
InterfaceMemberBase imb = symbol as InterfaceMemberBase;
if (imb == null || !imb.IsExplicitImpl) {
Report.SymbolRelatedToPreviousError (this);
}
}
- public override ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
+ public override IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
{
DeclSpace top_level = Parent;
if (top_level != null) {
top_level = top_level.Parent;
var candidates = NamespaceEntry.NS.LookupExtensionMethod (extensionType, this, name, arity);
- if (candidates != null)
- return new ExtensionMethodGroupExpr (candidates, NamespaceEntry, extensionType, loc);
+ if (candidates != null) {
+ scope = NamespaceEntry;
+ return candidates;
+ }
}
- return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity, loc);
+ return NamespaceEntry.LookupExtensionMethod (extensionType, name, arity, ref scope);
}
protected override TypeAttributes TypeAttr {
}
}
- public abstract class InterfaceMemberBase : MemberBase {
+ public abstract class InterfaceMemberBase : MemberBase
+ {
+ //
+ // Common modifiers allowed in a class declaration
+ //
+ protected const Modifiers AllowedModifiersClass =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE |
+ Modifiers.STATIC |
+ Modifiers.VIRTUAL |
+ Modifiers.SEALED |
+ Modifiers.OVERRIDE |
+ Modifiers.ABSTRACT |
+ Modifiers.UNSAFE |
+ Modifiers.EXTERN;
+
+ //
+ // Common modifiers allowed in a struct declaration
+ //
+ protected const Modifiers AllowedModifiersStruct =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE |
+ Modifiers.STATIC |
+ Modifiers.OVERRIDE |
+ Modifiers.UNSAFE |
+ Modifiers.EXTERN;
+
+ //
+ // Common modifiers allowed in a interface declaration
+ //
+ protected const Modifiers AllowedModifiersInterface =
+ Modifiers.NEW |
+ Modifiers.UNSAFE;
+
//
// Whether this is an interface member.
//
}
}
- if (!IsInterface && base_member.IsAbstract) {
+ if (!IsInterface && base_member.IsAbstract && candidate == null) {
Report.SymbolRelatedToPreviousError (base_member);
Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
GetSignatureForError (), base_member.GetSignatureForError ());
{
bool ok = true;
- if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE | Modifiers.OVERRIDE_UNCHECKED)) == 0) {
+ if ((base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0) {
Report.SymbolRelatedToPreviousError (base_member);
Report.Error (506, Location,
"`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",