[svn] r7454: nemerle/trunk: macros/Logging.n macros/Util.n ncc/testsuite/positive/accessor-macros.n

iae svnadmin at nemerle.org
Tue Feb 20 18:08:38 CET 2007


Log:
Changes in 2 macroses: Logging relative and Accessor.
 

Logging package:

     The feature, which allows to change detail level of logging not 
     only in compile-time, but after deployment, is very useful. 
     However, logging package allows to change detail level only in
     compile-time with help of LogFlag macro.

     [assembly: LogFlag (Debug, false)]
     [assembly: LogFlag (Info,  true)]
     ...

     So, in spite of such package as Logging is very useful it isn't 
     enough flexible. A lot of .NET developers use logging 
     frameworks like log4net. There are several ways to change logs 
     detail level including changes in config files. So, I made 
     non-breaking changes in behavior of Logging package which
     allows users to specify not just true/false/1/0, but also 
     expressions. Let's consider an example. Just imagine that we
     have logger instance MyLib.Logger. So, we can describe
     our logger in such a way:

     [assembly: LogCondition (MyLib.Logger != null)]
     [assembly: LogFunction (Debug => MyLib.Logger.Debug, 
                             Info  => MyLib.Logger.Info ,
                             Warn  => MyLib.Logger.Warn ,
                             Error => MyLib.Logger.Error,
                             Fatal => MyLib.Logger.Fatal,
                            )]
     [assembly: LogFlag (Debug, MyLib.Logger.IsDebugEnabled)]
     [assembly: LogFlag (Info,  MyLib.Logger.IsInfoEnabled )]
     [assembly: LogFlag (Warn,  MyLib.Logger.IsWarnEnabled )]
     [assembly: LogFlag (Error, MyLib.Logger.IsErrorEnabled)]
     [assembly: LogFlag (Fatal, MyLib.Logger.IsFatalEnabled)]

     And use them:

     log(Debug, $"value of `someVariable' is `$someVariable'");

     The bonus we have here is that expanding of splice will take 
     place only when MyLib.Logger.IsDebugEnabled is true.


Accessor:

     Sometimes, it is necessary to add some custom attributes to 
     property (which is created by Accessor macro). So, I add 
     `attributes' param to macro:

     [Accessor (flags = WantSetter, 
                attributes(System.CLSCompliant(true), AnyOther))]
     mutable cls_compilant_and_any_other : string = "cls&any";

     Result is:

     [System.CLSCompliant(true), AnyOther]
     public ClsCompilantAndAnyOther : string
     { get {...} set {...} }


Author: iae
Date: Tue Feb 20 18:08:35 2007
New Revision: 7454

Modified:
   nemerle/trunk/macros/Logging.n
   nemerle/trunk/macros/Util.n
   nemerle/trunk/ncc/testsuite/positive/accessor-macros.n

Modified: nemerle/trunk/macros/Logging.n
==============================================================================
--- nemerle/trunk/macros/Logging.n	(original)
+++ nemerle/trunk/macros/Logging.n	Tue Feb 20 18:08:35 2007
@@ -37,7 +37,7 @@
 {
   internal module Helper
   {
-    public Flags : Hashtable [string, bool] = Hashtable ();
+    public Flags : Hashtable [string, PExpr] = Hashtable ();
     
     // empty string holds default print function (also set when no VERB=>expr mapping is specified)
     public FlagsToFunctions : Hashtable [string, PExpr] = Hashtable ();
@@ -68,13 +68,9 @@
     public LogFlag (id : PExpr, is_on : PExpr) : void {
       def is_on =
         match (is_on) {
-          | <[ true ]>
-          | <[ 1 ]> => true
-          | <[ false ]>
-          | <[ 0 ]> => false
-          | _ =>
-            Message.Error ("flag value should be either true/false (or 0/1)"); 
-            false
+          | <[ 1 ]> => <[ true ]>
+          | <[ 0 ]> => <[ false ]>
+          | _ => is_on
         }
       def name = GetName (id);
       when (Flags.Contains (name))
@@ -184,11 +180,13 @@
       else exprs;
       
     if (Flags.Contains (name))
-      if (Flags [name])
-        AddCondition (<[ $print_expr (.. $exprs) ]>)
-      else <[ {} ]>
+      match (Flags [name]) {
+        | <[ true ]> => AddCondition (<[ $print_expr (.. $exprs) ]>)
+        | <[ false ]> => <[ {} ]>
+        | _ => AddCondition (<[ when($(Flags [name])) { $print_expr (.. $exprs) } ]>)
+      }
     else {
-      Message.Error ($ "there is no debug flag named `$(name)'");
+      Message.Error ($ "there is no flag named `$(name)'");
       <[ {} ]>
     }
   }
@@ -198,10 +196,13 @@
   {
     def name = GetName (flag);
     if (Flags.Contains (name))
-      if (Flags [name]) body
-      else <[ {} ]>
+      match (Flags [name]) {
+        | <[ true ]> => body
+        | <[ false ]> => <[ {} ]>
+        | _ => <[ when($(Flags [name])) { $body } ]>
+      }
     else {
-      Message.Error ($ "there is no debug flag named `$(name)'");
+      Message.Error ($ "there is no flag named `$(name)'");
       <[ {} ]>
     }
   }

Modified: nemerle/trunk/macros/Util.n
==============================================================================
--- nemerle/trunk/macros/Util.n	(original)
+++ nemerle/trunk/macros/Util.n	Tue Feb 20 18:08:35 2007
@@ -64,9 +64,14 @@
                        Inherited = false, AllowMultiple = true)]
   macro Accessor (current_type : TypeBuilder, storage_field : ParsedField, params args : list [PExpr])
   {
+    def usage =
+        "usage: Accessor (name, flags = MODIFIERS, get (MODIFIERS), set (MODIFIERS), "
+        "attributes (LIST OF ATTRIBUTES)), where all sections are optional";
+
     mutable setterMods = NemerleAttributes.None;
     mutable getterMods = NemerleAttributes.Public;
     mutable want_setter = false;
+    mutable attributes = [];
     mutable oname = None ();
 
     def parse_opts (expr, allow_deprec) {
@@ -97,9 +102,9 @@
           setterMods |= getterMods;
       | <[ set ($opts) ]> => setterMods |= parse_opts (opts, false)
       | <[ get ($opts) ]> => getterMods |= parse_opts (opts, false)
+      | <[ attributes (..$attrs) ]> => attributes += attrs
       | _ =>
-        Message.FatalError ("usage: Accessor (name, flags = MODIFIERS, get (MODIFIERS), set (MODIFIERS)), "
-                            "where all sections are optional");
+        Message.FatalError (usage);
     }
 
     // __some_foo__bar ==> SomeFooBar
@@ -140,10 +145,12 @@
     def fieldref = <[ $(storage_field.ParsedName : name) ]>;
     def setterAttrs = Modifiers (setterMods, [<[ System.Diagnostics.DebuggerStepThroughAttribute ]>]);
     def getterAttrs = Modifiers (getterMods, [<[ System.Diagnostics.DebuggerStepThroughAttribute ]>]);
+    def propAttrs = Modifiers (NemerleAttributes.None, attributes);
 
     def prop = 
       if (setterMods != NemerleAttributes.None && getterMods != NemerleAttributes.None)
         <[ decl:
+          ..$propAttrs
           $(name : dyn) : $(storage_field.ty)
           {
             ..$setterAttrs set { $fieldref = value; }
@@ -152,6 +159,7 @@
         ]>
       else if (getterMods != NemerleAttributes.None)
         <[ decl:
+          ..$propAttrs
           $(name : dyn) : $(storage_field.ty)
           {
             ..$getterAttrs get { $fieldref }
@@ -159,6 +167,7 @@
         ]>;
       else if (setterMods != NemerleAttributes.None)
         <[ decl:
+          ..$propAttrs
           $(name : dyn) : $(storage_field.ty)
           {
             ..$setterAttrs set { $fieldref = value }

Modified: nemerle/trunk/ncc/testsuite/positive/accessor-macros.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/accessor-macros.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/accessor-macros.n	Tue Feb 20 18:08:35 2007
@@ -1,4 +1,5 @@
 using Nemerle.Utility;
+using Nemerle.Builtins.Function;
 
 [System.Flags]
 enum SomeFlags {
@@ -23,6 +24,8 @@
   mutable bar : string = "qux";
 }
 
+class AnyAttribute : System.Attribute {}
+
 class C
 {
   [Accessor]
@@ -40,6 +43,9 @@
   [Accessor (flags = WantSetter | Internal)]
   static mutable static_field : string = "foo";
 
+  [Accessor (flags = WantSetter, 
+             attributes(System.CLSCompliant(true), Any))]
+  mutable cls_compilant_and_any : string = "cls&any";
 
   [FlagAccessor (Flag1, Flag2, flags = WantSetter | Protected)]
   [FlagAccessor (Flag3)]
@@ -67,6 +73,18 @@
     assert (typeof (C).GetMethod ("set_SomeField") == null);
     assert (typeof (C).GetMethod ("get_SomeField") != null);
 
+    def checkAttrs(t)
+    {
+      typeof (C)
+        .GetProperty("ClsCompilantAndAny")
+        .GetCustomAttributes(t, true)
+        .Length == 1
+    }
+    c.ClsCompilantAndAny = "bla";
+    System.Console.WriteLine (c.ClsCompilantAndAny);
+    assert (typeof (AnyAttribute) |> checkAttrs);
+    assert (typeof (System.CLSCompliantAttribute) |> checkAttrs);
+
     assert (!c.Flag1);
     assert (!c.Flag2);
     assert (!c.Flag3);
@@ -91,5 +109,6 @@
 42
 True
 qux
+bla
 END-OUTPUT
 */



More information about the svn mailing list