using System.Reflection.Emit;
using System.Reflection;
-namespace Mono.CSharp {
+namespace Mono.MonoBASIC {
/// <summary>
/// Base representation for members. This is only used to keep track
protected void WarningNotHiding (TypeContainer parent)
{
- Report.Warning (
+ /*Report.Warning (
109, Location,
"The member " + parent.MakeName (Name) + " does not hide an " +
"inherited member. The keyword new is not required");
-
+ */
}
void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method,
MethodInfo mb, string name)
{
bool ok = true;
-
+
if ((ModFlags & Modifiers.OVERRIDE) != 0){
- if (!(mb.IsAbstract || mb.IsVirtual)){
+ // Now we check that the overriden method is not final
+ if (mb.IsFinal) \r
+ {
+ Report.Error (30267, Location, parent.MakeName (Name) + " : cannot " +
+ "override inherited member `" + name +
+ "' because it is NotOverridable.");
+ ok = false;
+ }
+ else if (!(mb.IsAbstract || mb.IsVirtual)){
Report.Error (
- 506, Location, parent.MakeName (Name) +
- ": cannot override inherited member `" +
+ 31086, Location, parent.MakeName (Name) +
+ ": Cannot override inherited member `" +
name + "' because it is not " +
- "virtual, abstract or override");
+ "declared as Overridable");
ok = false;
}
- // Now we check that the overriden method is not final
-
- if (mb.IsFinal) {
- Report.Error (239, Location, parent.MakeName (Name) + " : cannot " +
- "override inherited member `" + name +
- "' because it is sealed.");
- ok = false;
- }
-
//
// Check that the permissions are not being changed
//
}
}
- if (mb.IsVirtual || mb.IsAbstract){
- if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
+ if ((ModFlags & ( Modifiers.NEW | Modifiers.SHADOWS | Modifiers.OVERRIDE )) == 0) {
+ if ((ModFlags & Modifiers.NONVIRTUAL) != 0) {
+ Report.Error (31088, Location,
+ parent.MakeName (Name) + " cannot " +
+ "be declared NotOverridable since this method is " +
+ "not marked as Overrides");
+ }
+ }
+
+ if (mb.IsAbstract) {
+ if ((ModFlags & (Modifiers.OVERRIDE)) == 0) {
+ if (Name != "Finalize") {
+ Report.Error (
+ 31404, Location,
+ name + " cannot Shadows the method " +
+ parent.MakeName (Name) + " since it is declared " +
+ "'MustOverride' in base class");
+ }
+ }
+ }
+ else if (mb.IsVirtual){
+ if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SHADOWS)) == 0){
if (Name != "Finalize"){
Report.Warning (
- 114, 2, Location, parent.MakeName (Name) +
- " hides inherited member `" + name +
+ 40005, 2, Location, parent.MakeName (Name) +
+ " shadows overridable member `" + name +
"'. To make the current member override that " +
- "implementation, add the override keyword, " +
- "otherwise use the new keyword");
- ModFlags |= Modifiers.NEW;
+ "implementation, add the overrides keyword." );
+ ModFlags |= Modifiers.SHADOWS;
}
}
- } else {
- if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0){
+ }
+ else {
+ if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE |
+ Modifiers.SHADOWS)) == 0){
if (Name != "Finalize"){
Report.Warning (
- 108, 1, Location, "The keyword new is required on " +
+ 40004, 1, Location, "The keyword Shadows is required on " +
parent.MakeName (Name) + " because it hides " +
"inherited member `" + name + "'");
- ModFlags |= Modifiers.NEW;
+ ModFlags |= Modifiers.SHADOWS;
}
}
}
/// </summary>
public string LookupAlias (string name)
{
- if (Namespace != null)
- return Namespace.LookupAlias (name);
- else
- return null;
+ return RootContext.SourceBeingCompiled.LookupAlias (name);
}
//
if (type_resolve_ec == null)
type_resolve_ec = GetTypeResolveEmitContext (parent, loc);
type_resolve_ec.loc = loc;
+
+ int errors = Report.Errors;
Expression d = e.Resolve (type_resolve_ec, ResolveFlags.Type);
if (d == null || d.eclass != ExprClass.Type){
- if (!silent){
+ if (!silent && errors == Report.Errors){
Report.Error (246, loc, "Cannot find type `"+ e.ToString () +"'");
}
return null;
t = parent.DefineType ();
if (t == null){
- Report.Error (146, "Class definition is circular: `"+name+"'");
+ Report.Error (30256, Location, "Class definition is circular: `"+name+"'");
error = true;
return null;
}
return t;
}
-
+
+ public static void Error_AmbiguousTypeReference (Location loc, string name, Type t1, Type t2)
+ {
+ Report.Error (104, loc,
+ String.Format ("`{0}' is an ambiguous reference ({1} or {2}) ", name,
+ t1.FullName, t2.FullName));
+ }
+
/// <summary>
/// GetType is used to resolve type names at the DeclSpace level.
/// Use this to lookup class/struct bases, interface bases or
/// during the tree resolution process and potentially define
/// recursively the type
/// </remarks>
- public Type FindType (string name)
+ public Type FindType (Location loc, string name)
{
Type t;
bool error;
//
// Now check the using clause list
//
- ArrayList using_list = ns.UsingTable;
-
- if (using_list == null)
- continue;
-
- foreach (Namespace.UsingEntry ue in using_list){
- t = LookupInterfaceOrClass (ue.Name, name, out error);
+ ICollection imports_list = RootContext.SourceBeingCompiled.ImportsTable;\r
+\r
+ if (imports_list == null)\r
+ continue;\r
+
+ Type match = null;
+ foreach (SourceBeingCompiled.ImportsEntry ue in imports_list){
+ match = LookupInterfaceOrClass (ue.Name, name, out error);
if (error)
return null;
- if (t != null){
+ if (match != null){
+ if (t != null){
+ Error_AmbiguousTypeReference (loc, name, t, match);
+ return null;
+ }
+
+ t = match;
ue.Used = true;
- return t;
}
}
-
+ if (t != null)
+ return t;
}
//Report.Error (246, Location, "Can not find type `"+name+"'");
/// </summary>
public class MemberCache {
public readonly IMemberContainer Container;
- protected Hashtable member_hash;
- protected Hashtable method_hash;
+ protected CaseInsensitiveHashtable member_hash;
+ protected CaseInsensitiveHashtable method_hash;
+ protected CaseInsensitiveHashtable interface_hash;
/// <summary>
/// Create a new MemberCache for the given IMemberContainer `container'.
Timer.IncrementCounter (CounterType.MemberCache);
Timer.StartTimer (TimerType.CacheInit);
+ interface_hash = new CaseInsensitiveHashtable ();
+
// If we have a parent class (we have a parent class unless we're
// TypeManager.object_type), we deep-copy its MemberCache here.
if (Container.Parent != null)
else if (Container.IsInterface)
member_hash = SetupCacheForInterface ();
else
- member_hash = new Hashtable ();
+ member_hash = new CaseInsensitiveHashtable ();
// If this is neither a dynamic type nor an interface, create a special
// method cache with all declared and inherited methods.
Type type = container.Type;
if (!(type is TypeBuilder) && !type.IsInterface) {
- method_hash = new Hashtable ();
+ method_hash = new CaseInsensitiveHashtable ();
AddMethods (type);
}
/// <summary>
/// Bootstrap this member cache by doing a deep-copy of our parent.
/// </summary>
- Hashtable SetupCache (MemberCache parent)
+ CaseInsensitiveHashtable SetupCache (MemberCache parent)
{
- Hashtable hash = new Hashtable ();
+ CaseInsensitiveHashtable hash = new CaseInsensitiveHashtable ();
IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
while (it.MoveNext ()) {
return hash;
}
+ void AddInterfaces (MemberCache parent)
+ {
+ foreach (Type iface in parent.interface_hash.Keys) {
+ if (!interface_hash.Contains (iface))
+ interface_hash.Add (iface, true);
+ }
+ }
+
/// <summary>
/// Add the contents of `new_hash' to `hash'.
/// </summary>
/// Type.GetMembers() won't return any inherited members for interface types,
/// so we need to do this manually. Interfaces also inherit from System.Object.
/// </summary>
- Hashtable SetupCacheForInterface ()
+ CaseInsensitiveHashtable SetupCacheForInterface ()
{
- Hashtable hash = SetupCache (TypeHandle.ObjectType.MemberCache);
+ CaseInsensitiveHashtable hash = SetupCache (TypeHandle.ObjectType.MemberCache);
Type [] ifaces = TypeManager.GetInterfaces (Container.Type);
foreach (Type iface in ifaces) {
+ if (interface_hash.Contains (iface))
+ continue;
+ interface_hash.Add (iface, true);
+
IMemberContainer iface_container =
TypeManager.LookupMemberContainer (iface);
MemberCache iface_cache = iface_container.MemberCache;
AddHashtable (hash, iface_cache.member_hash);
+ AddInterfaces (iface_cache);
}
return hash;
// If we have a method cache and we aren't already doing a method-only search,
// then we restart a method search if the first match is a method.
bool do_method_search = !method_search && (method_hash != null);
-
+bf |= BindingFlags.IgnoreCase;
ArrayList applicable;
// If this is a method-only search, we try to use the method cache if