[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