[svn] r6387: nemerle/trunk/macros/alias.n

d svnadmin at nemerle.org
Thu Jun 8 22:33:23 CEST 2006


Log:
Support further aliasing possibilities (two unsupported left), add propagating access modifiers from source, to generated methods/properties.


Author: d
Date: Thu Jun  8 22:33:22 2006
New Revision: 6387

Modified:
   nemerle/trunk/macros/alias.n

Modified: nemerle/trunk/macros/alias.n
==============================================================================
--- nemerle/trunk/macros/alias.n	(original)
+++ nemerle/trunk/macros/alias.n	Thu Jun  8 22:33:22 2006
@@ -41,9 +41,8 @@
    * to be "intelligent" in it's choices (which basically means, 
    * that only reasonable possibilities are taken into account).
    *
-   * TODO: write code for aliasing non-static methods (see "not 
-   *       supported yet" below), properties and fields as well
-   *       as handling attributes like private, override etc.
+   * TODO: write code for the two remaining unsupported alias types,
+   *       aliasing properties and fields.
    *
    ***** Example #1:
    *
@@ -76,102 +75,121 @@
    ***** Example #3:
    *
    * [Alias (Nth (i, l), Lookup (i))]
-   * static Nth (xs : RList ['a], i : int) { some_code }
+   * public static Nth (xs : RList ['a], i : int) { some_code }
    *
    * // generates the following code:
    *
-   * static Nth (i : int, xs : RList ['a]) { some_code }
-   * Lookup (i : int) { def xs = this; some_code }
-   *
-   ***************** NOT SUPPORTED (YET) STUFF BELOW *****************
+   * public static Nth (i : int, xs : RList ['a]) { some_code }
+   * public Lookup (i : int) { def xs = this; some_code }
    *
    ***** Example #4:
    *
-   * [Alias (F1, F2 (), F3 (x)] 
+   * [Alias (F1, F2 (), F3 (x))] 
    * public F () : t { ... }
    *
    * // generates the following code:
    *
    * public F1 : t { get { ... } }
    * public F2 () t { ... }
-   * public static F3 (x : this) : t { ... } // [x] <-> [this]
+   * public static F3 (x : this) : t { ... } // [x] <-> [this] // NOT SUPPORTED YET
    *
    ***** Example #5:
    *
-   * [Alias (F1 (x, y), F2 (x, y, z)] 
+   * [Alias (F1 (x, y), F2 (x, y, z))] 
    * public F (x : t1, y : t2) : t3 { ... }
    *
    * // generates the following code:
    *
    * public F1 (x : t1, y : t2) : t3 { ... }
-   * public static F2 (x : t1, y : t2, z : this) : t3 { ... } // [z] <-> [this]
+   * public static F2 (x : t1, y : t2, z : this) : t3 { ... } // [z] <-> [this] // NOT SUPPORTED YET
    *
    */
   [Nemerle.MacroUsage (Nemerle.MacroPhase.WithTypedMembers,
                        Nemerle.MacroTargets.Method)]
   macro Alias (tb : TypeBuilder, meth : MethodBuilder, params opts : list [PExpr]) {
     def parms = meth.GetParameters ();
-    if (meth.IsStatic) 
+    def mods = meth.GetModifiers ();
+    def make_non_static (na : NemerleAttributes) { 
+      na & (NemerleAttributes.Static :> int - 1) :> NemerleAttributes 
+    }
       match (parms.Length) {
         | 0 => 
           foreach (o in opts) {
-            | <[ $alias_name () ]> => // [Alias (G ())] static F ()
+          | <[ $alias_name () ]> => // [Alias (G ())] static F () or [Alias (G ())] F ()
+            def new_mods = Modifiers (mods.Attributes, mods.GetCustomAttributes ());
               tb.Define (<[ decl: 
-                public static $(alias_name.ToString () : usesite) () 
-                              : $(meth.ReturnType : typed) { 
+              ..$new_mods $(alias_name.ToString () : usesite) () : $(meth.ReturnType : typed) { 
                   $(meth.Body) 
                 }
               ]>) 
-            | <[ $_ (.. $_) ]> => // e.g. [Alias (G (x)] static F ()
+          | <[ $_alias_name ($_alias_parm) ]> => 
+            if (meth.IsStatic) 
+              Message.Error ($"Invalid parameter count for alias: $o.")
+            else  // e.g. [Alias (G (x)] F ()
+              Message.Error ($"This type of aliasing is not implemented yet: $o.");
+          | <[ $_ (.. $_) ]> => 
               Message.Error ($"Invalid parameter count for alias: $o.")
-            | <[ $alias_name ]> => // [Alias (G)] static F ()
+          | <[ $alias_name ]> => // [Alias (G)] static F () or [Alias (G)] F ()
+            def new_mods = Modifiers (make_non_static (mods.Attributes), mods.GetCustomAttributes ());
               tb.Define (<[ decl: 
-                public $(alias_name.ToString () : usesite) : $(meth.ReturnType : typed) { 
+              ..$new_mods $(alias_name.ToString () : usesite) : $(meth.ReturnType : typed) { 
                   get { $(meth.Body) }
                 }
               ]>) 
           }
         | 1 => 
           foreach (o in opts) {
-            | <[ $alias_name () ]> => // [Alias (G ())] static F (x) /* [x] <-> [this] */
+          | <[ $alias_name () ]> => 
+            if (meth.IsStatic) { // [Alias (G ())] static F (x) // [x] <-> [this] 
+              def new_mods = Modifiers (make_non_static (mods.Attributes), mods.GetCustomAttributes ());
               tb.Define (<[ decl: 
-                public $(alias_name.ToString () : usesite) () : $(meth.ReturnType : typed) { 
+                ..$new_mods $(alias_name.ToString () : usesite) () : $(meth.ReturnType : typed) { 
                   def $(parms.Head.name.ToString () : usesite) = this; 
                   $(meth.Body) 
                 }
               ]>) 
+            }
+            else
+              Message.Error ($"Invalid parameter count for alias: $o.")
 
-            | <[ $alias_name ($alias_parm) ]> => // [Alias (G (x))] static F (x)
+          | <[ $alias_name ($alias_parm) ]> => 
+            // [Alias (G (x))] static F (x) or [Alias (G (x))] static F (x)
+            def new_mods = Modifiers (mods.Attributes, mods.GetCustomAttributes ());
               def parm = parms.Head;
               when (parm.name.ToString () != alias_parm.ToString ()) 
                 Message.Error ($"Invalid parameter name for alias: $o.");
               tb.Define (<[ decl: 
-                static public $(alias_name.ToString () : usesite) 
+              ..$new_mods $(alias_name.ToString () : usesite) 
                               ($(parm.name.ToString () : usesite) : $(parm.ty : typed)) 
                               : $(meth.ReturnType : typed) { 
                   $(meth.Body) 
                 }
               ]>) 
 
-            | <[ $alias_name ]> => // [Alias (G)] static F (x) /* [x] <-> [this] */
+          | <[ $alias_name ]> => // [Alias (G)] static F (x) // [x] <-> [this] 
+            def new_mods = Modifiers (make_non_static (mods.Attributes), mods.GetCustomAttributes ());
+            if (meth.IsStatic)
               tb.Define (<[ decl: 
-                public $(alias_name.ToString () : usesite) : $(meth.ReturnType : typed) { 
+                ..$new_mods $(alias_name.ToString () : usesite) : $(meth.ReturnType : typed) { 
                   get { def $(parms.Head.name.ToString () : usesite) = this; $(meth.Body) }
                 }
               ]>) 
+            else
+              Message.Error ($"Invalid parameter name for alias: $o.");
           }
         | parms_num =>
           foreach (o in opts) {
             | <[ $alias_name (.. $alias_parms) ]> => 
               match (parms_num - alias_parms.Length) {
-                | 0 => // e.g. [Alias (G (x, y))] static F (x, y)
+              | 0 => // e.g. [Alias (G (x, y))] static F (x, y) or [Alias (G (x, y))] F (x, y)
+                def new_mods = Modifiers (mods.Attributes, mods.GetCustomAttributes ());
                   def parm_dict = Hashtable ();
                   List.Iter (parms, p => parm_dict.Add (p.Name.ToString (), p.ty));
                   try { 
                     def fparms = List.Map (alias_parms, p => <[ parameter: $(p.ToString () : usesite) 
                                                                 : $(parm_dict [p.ToString ()] : typed) ]>);
                     tb.Define (<[ decl: 
-                      static public $(alias_name.ToString () : usesite) (..$fparms) 
+                   ..$new_mods $(alias_name.ToString () : usesite) (..$fparms) 
                                     : $(meth.ReturnType : typed) { 
                         $(meth.Body) 
                       }
@@ -181,7 +199,9 @@
                     | _ is SCG.KeyNotFoundException => 
                       Message.Error ($"Invalid parameter name for alias: $o.");
                   }
-                | 1 => // e.g. [Alias (G (x))] static F (x, y) /* [y] <-> [this] */
+              | 1 => // e.g. [Alias (G (x))] static F (x, y) // [y] <-> [this] 
+                if (meth.IsStatic) {
+                  def new_mods = Modifiers (make_non_static (mods.Attributes), mods.GetCustomAttributes ());
                   def parm_dict = Hashtable ();
                   List.Iter (parms, p => parm_dict.Add (p.Name.ToString (), p.ty));
                   try { 
@@ -194,7 +214,7 @@
                     def this_def = parm_dict.Fold (<[ () ]>, (k, v, _) => 
                                                      <[ def $(k : usesite) : $(v : typed) = this ]>);
                     tb.Define (<[ decl: 
-                      public $(alias_name.ToString () : usesite) (..$fparms) 
+                      ..$new_mods $(alias_name.ToString () : usesite) (..$fparms) 
                                : $(meth.ReturnType : typed) { 
                         $this_def;
                         $(meth.Body) 
@@ -205,11 +225,18 @@
                     | _ is SCG.KeyNotFoundException => 
                       Message.Error ($"Invalid parameter name for alias: $o.");
                   }
+                }
+                else
+                  Message.Error ($"Invalid parameter count for alias: $o.");
+              | -1 =>
+                if (meth.IsStatic) 
+                  Message.Error ($"Invalid parameter count for alias: $o.");
+                else // [Alias (G (x, y, z))] F (x, y) // [z] <-> [this]
+                  Message.Error ($"This type of aliasing is not implemented yet: $o.");
                 | _ => Message.Error ($"Invalid parameter count for alias: $o.");
               }
+          | _ => () // unreachable
           }
       }
-    else
-      Message.Error ("Sorry, aliasing non-static methods is not yet supported!")
   }
 }



More information about the svn mailing list