[svn] r6449: nemerle/trunk/ncc: hierarchy/TypeBuilder.n testsuite/negative/derived.n testsuite/negative/tc...

nazgul svnadmin at nemerle.org
Thu Jul 13 22:20:16 CEST 2006


Log:
Allow reimplementing methods from directly implemeneted interfaces

Author: nazgul
Date: Thu Jul 13 22:20:13 2006
New Revision: 6449

Modified:
   nemerle/trunk/ncc/hierarchy/TypeBuilder.n
   nemerle/trunk/ncc/testsuite/negative/derived.n
   nemerle/trunk/ncc/testsuite/negative/tc.n
   nemerle/trunk/ncc/testsuite/positive/qualified-interface-method.n

Modified: nemerle/trunk/ncc/hierarchy/TypeBuilder.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/TypeBuilder.n	(original)
+++ nemerle/trunk/ncc/hierarchy/TypeBuilder.n	Thu Jul 13 22:20:13 2006
@@ -849,24 +849,23 @@
   public InterfacesToImplement () : list [TypeInfo] 
   {
     def base_class =
-      match (SuperClass ()) {
-        | Some (tc) => tc
-        | None => InternalType.Object_tc
+      match (parent_type) {
+        | null => InternalType.Object_tc
+        | _ => parent_type.tycon
       };
 
     def collect (t : MType.Class, acc) {
       def tc = t.tycon;
       if (tc.IsInterface) {
         match (base_class.SuperType (tc)) {
-          | Some => acc
+         | Some =>acc
           | None => tc :: acc
         }
       }
       else
         acc
     };
-    
-    List.FoldLeft (GetSuperTypes (), [], collect);
+    GetSuperTypes ().FoldLeft ([], collect);
   }
 
   //------------ METHODS FOR TYPING --------------------------------------  
@@ -1124,6 +1123,11 @@
       }
     }
 
+    // detect non-interfaces
+    foreach (t in t_implements)
+      unless (t.tycon.IsInterface)
+        Message.Error ($"base class `$t' must be specified as first");
+    
     when (is_enum)  handle_underlying_enum_type ();
 
     when (IsStruct)
@@ -2012,6 +2016,7 @@
 
     // unresolved interface methods, which we must implement
     def iface_methods = Hashtable (30);
+    def can_explicitly_impl_methods = Hashtable ();
 
     def method_type_ok (iface_meth, meth) {
       def h1 = iface_meth.GetHeader ();
@@ -2046,8 +2051,7 @@
       List.Partition (ifmethods, is_correct)
     }
     
-    foreach (tc : TypeInfo in InterfacesToImplement ()) {
-      // Message.Debug ($ "in $this, $tc .GetMembers == $(tc.GetMembers (BindingFlags.DeclaredOnly %| BindingFlags.Public %| BindingFlags.Instance))");
+    def collect_methods (tc, iface_methods) {
       foreach (m : IMember in tc.GetMembers (BindingFlags.DeclaredOnly %|
                                              BindingFlags.Public %|
                                              BindingFlags.Instance))
@@ -2061,6 +2065,13 @@
         }
     }
 
+    foreach (tc : TypeInfo in InterfacesToImplement ()) {
+      // Message.Debug ($ "in $this, $tc .GetMembers == $(tc.GetMembers (BindingFlags.DeclaredOnly %| BindingFlags.Public %| BindingFlags.Instance))");
+       collect_methods (tc, iface_methods);
+    }
+    foreach (mtype in t_implements)
+       collect_methods (mtype.tycon, can_explicitly_impl_methods);
+
     def bind_explicit_implements (meth : MethodBuilder)
     {
       def bind_one (impl)
@@ -2070,33 +2081,50 @@
             def env = name.context;
             def (ns, member) = List.DivideLast (idl);
             def ty = env.GetType (ns, this, -1);
-
-            match (iface_methods.Get (member)) {
-              | Some (meths) =>
                 def is_correct (iface_meth : IMethod) {
                   iface_meth.DeclaringType.Equals (ty) &&
                   method_type_ok (iface_meth, meth)
                 };
+
+            ManagerClass.Instance.MarkAsUsed (meth);
+            
+            match (iface_methods.Get (member)) {
+              | Some (meths) =>
                 def (correct, notcorrect) = List.Partition (meths, is_correct);
                 match (correct) {
                   | [] =>
-                    Message.FatalError ("interface `" + ty.FullName + 
-                                         "' does not contain method named `" + member + 
-                                         "' with proper signature")
+                    Message.FatalError ($"interface `$(ty.FullName)' does not contain method named"
+                                        " `$member' with proper signature")
                   | [m] =>                
                     iface_methods.Set (member, notcorrect);
-                    ManagerClass.Instance.MarkAsUsed (meth);
                     m
                   | _ =>
-                    Message.FatalError ("interface `" + ty.FullName + 
-                                         "' contains more then one method named `" + member + 
-                                         "' with proper signature")
+                    Message.FatalError ($"interface `$(ty.FullName)' contains more then one method"
+                                        " named `$member' with proper signature")
                 }
               | None =>
+                match (can_explicitly_impl_methods.Get (member)) {
+                  | Some (meths) =>
+                    def (correct, notcorrect) = List.Partition (meths, is_correct);
+                    match (correct) {
+                      | [] =>
+                        Message.FatalError ($"interface `$(ty.FullName)' does not contain method named"
+                                            " `$member' with proper signature")
+                      | [m] =>                
+                        can_explicitly_impl_methods.Set (member, notcorrect);
+                        m
+                      | _ =>
+                        Message.FatalError ($"interface `$(ty.FullName)' contains more then one method"
+                                            " named `$member' with proper signature")
+                    }
+
+                  | _ => 
                 Message.FatalError ($ "no interface implemented by `$FullName' " 
                                      "contains method named `$member' " 
                                      "(looking for `$(Util.QidOfList (idl))')")
             }
+            }
+                
           | _ => Message.FatalError ("simple identifier expected in explicit implementation specifier")
         }
       };

Modified: nemerle/trunk/ncc/testsuite/negative/derived.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/derived.n	(original)
+++ nemerle/trunk/ncc/testsuite/negative/derived.n	Thu Jul 13 22:20:13 2006
@@ -2,3 +2,4 @@
 class A : array [int] // E: derived or implemented type must be a class
 {
 }
+

Modified: nemerle/trunk/ncc/testsuite/negative/tc.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/tc.n	(original)
+++ nemerle/trunk/ncc/testsuite/negative/tc.n	Thu Jul 13 22:20:13 2006
@@ -22,3 +22,7 @@
     foo (x : 'a) : void {} // OK
   }
 }
+
+interface IA {}
+class Base { }
+class B : IA, Base { } // E: base class `Base' must be specified as first

Modified: nemerle/trunk/ncc/testsuite/positive/qualified-interface-method.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/qualified-interface-method.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/qualified-interface-method.n	Thu Jul 13 22:20:13 2006
@@ -1,3 +1,5 @@
+using System;
+
 public interface I
 {
   f ['a] (_ : 'a) : void;
@@ -10,3 +12,38 @@
   {
   }
 }
+
+
+public interface ISomething
+{
+  DoSomething() : void;
+}
+
+public class Something: ISomething
+{
+  ISomething_DoSomething() : void implements ISomething.DoSomething
+  {
+    Console.WriteLine("Something.DoSomething");
+  }
+}
+
+public class Something2:  Something, ISomething
+{
+  
+  ISomething_DoSomething() : void implements ISomething.DoSomething
+  {
+    Console.WriteLine("Something2.DoSomething");
+  }
+    
+}
+
+((Something() : ISomething)).DoSomething();
+((Something2() : ISomething)).DoSomething();
+
+
+/*
+BEGIN-OUTPUT
+Something.DoSomething
+Something2.DoSomething
+END-OUTPUT
+*/



More information about the svn mailing list