[svn] r7748: nemerle/trunk/snippets/aop: . makefile src/ftests/type_pattern/advice_parms_positive.n src/he...

Luntain svnadmin at nemerle.org
Tue Jul 10 17:06:36 CEST 2007


Log:
use type pattern in place of a type of an advice formal parameter

Author: Luntain
Date: Tue Jul 10 17:06:06 2007
New Revision: 7748

Added:
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/advice_parms_positive.n
Modified:
   nemerle/trunk/snippets/aop/   (props changed)
   nemerle/trunk/snippets/aop/makefile
   nemerle/trunk/snippets/aop/src/helper/Parse.n
   nemerle/trunk/snippets/aop/src/helper/ParserCombinators.n
   nemerle/trunk/snippets/aop/src/helper/TypePattern.n
   nemerle/trunk/snippets/aop/src/macros/macros.n

Modified: nemerle/trunk/snippets/aop/makefile
==============================================================================
--- nemerle/trunk/snippets/aop/makefile	(original)
+++ nemerle/trunk/snippets/aop/makefile	Tue Jul 10 17:06:06 2007
@@ -9,7 +9,8 @@
 		src/dev_macros/parser_operators.n
 
 bin/Nemerle.Aop.dll: bin bin/DevMacros.dll src/macros/*.n src/helper/*.n
-	ncc -g -t:library -r Nemerle.Compiler.dll -m bin/DevMacros.dll -o:$@\
+	ncc --no-color -g -t:library -r Nemerle.Compiler.dll \
+		-m bin/DevMacros.dll -o:$@\
 		src/macros/*.n src/helper/*.n
 
 

Added: nemerle/trunk/snippets/aop/src/ftests/type_pattern/advice_parms_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/type_pattern/advice_parms_positive.n	Tue Jul 10 17:06:06 2007
@@ -0,0 +1,35 @@
+#pragma indent
+using Nemerle.IO
+using System.Collections
+using Nemerle.Aop
+
+public class A
+    public Method1['a](_:'a): void
+        print("meth\n")
+
+    public Method2['a](_:'a): void where 'a: ICollection
+        print("meth ICollection\n")
+
+    public M3(_:int): void
+        print("M3\n")
+
+
+    public static Main(): void
+        A().Method1(Stack())
+        A().Method2(Stack())
+        A().M3(2)
+
+[aspect] public class Aspekt {
+    before(_arg: ICollection+): execution(A.?(?): void) && args(_arg) {
+        print("advice\n")
+    }
+}
+
+/*
+BEGIN-OUTPUT
+meth
+advice
+meth ICollection
+M3
+END-OUTPUT
+*/

Modified: nemerle/trunk/snippets/aop/src/helper/Parse.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/helper/Parse.n	(original)
+++ nemerle/trunk/snippets/aop/src/helper/Parse.n	Tue Jul 10 17:06:06 2007
@@ -140,12 +140,16 @@
 
 
   public static type_pattern(tokens: list[Token], env: GlobalEnv): PResult[TypePattern] {
-
       def parse = type_pattern'(_,env,MTypePattern()) <@ mtypepattern => TypePattern.Make(mtypepattern); 
       parse(tokens)
   }
 
 
+  internal static param_pattern(tokens: list[Token], env: GlobalEnv): PResult[ParamPattern] {
+    def parse = type_pattern'(_,env,ParamPatternFactory());
+    parse(tokens)
+  }
+
   internal static type_pattern' ['a](tokens: list[Token], env: GlobalEnv, factory: TypePatternFactory['a]): PResult['a] {
 
    def parse_typepattern = reversed {

Modified: nemerle/trunk/snippets/aop/src/helper/ParserCombinators.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/helper/ParserCombinators.n	(original)
+++ nemerle/trunk/snippets/aop/src/helper/ParserCombinators.n	Tue Jul 10 17:06:06 2007
@@ -50,7 +50,6 @@
         public @<*['a,'b](parser1: Parser['a], parser2: Parser['b]): Parser['a] 
             parser1 <*> parser2 <@ (v1,_) => v1
 
-        // implements <@
         public @<@['a,'b](parse: Parser['a], f: 'a -> 'b ): Parser['b] 
             MapOutput(parse, (v,l) => PResult.OK(f(v),l), x=>PResult.Fail(x))
 

Modified: nemerle/trunk/snippets/aop/src/helper/TypePattern.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/helper/TypePattern.n	(original)
+++ nemerle/trunk/snippets/aop/src/helper/TypePattern.n	Tue Jul 10 17:06:06 2007
@@ -1,6 +1,7 @@
 #pragma indent
 
 using Nemerle.Compiler
+using Nemerle.Compiler.Parsetree
 using Nemerle.IO
 using System.Collections
 using Nemerle.Collections
@@ -64,6 +65,66 @@
             def vars = args.Map(t=> t.TyVars)
             MTypePatternData(MType.Tuple(arg_types), List.Flatten(vars), args.Map(x=>x.Text).ToString("*"))
             
+    [Record] class ParamPattern
+        [Accessor] pexpr: PExpr
+        [Accessor] tyvars: list[Splicable]
+        [Accessor] constraints: list[Constraint]
+
+        public this(pexpr: PExpr)
+            this(pexpr,[],[])
+
+    class ParamPatternFactory: TypePatternFactory[ParamPattern]
+        public Blank(): ParamPattern
+            def var_name = Util.tmpname("tyvar")
+            def name = Parsetree.Name(var_name)
+            def tyvar = Splicable.Name(name)
+            def pexpr = <[$(name: name)]>
+            ParamPattern(pexpr,[tyvar],[])
+
+        public Void(): ParamPattern
+            ParamPattern(<[void]>)
+
+        public ClassLike(full_name: list[string],args: list[ParamPattern], env: GlobalEnv): ParamPattern
+//            match (env.LookupType(full_name)) 
+//                | Some => 
+//                    ()
+//                | None => throw System.Exception($"class ..$(full_name;\".\") not found") 
+            def args_px = args.Map(a=> a.Pexpr)
+            def vars = args.Map(t=> t.Tyvars)
+            def constraints = args.Map(t=> t.Constraints) //TODO test param type with args
+            def fullname = Util.ExprOfList(full_name)
+            def pexpr = if (args_px.Length > 0)
+                <[$fullname [..$args_px]]>
+            else
+                fullname
+
+            ParamPattern(pexpr, List.Flatten(vars), List.Flatten(constraints)) 
+
+        public SubtypesOf(type_pattern: ParamPattern): ParamPattern
+            def var_name = Util.tmpname("tyvar")
+            def name = Parsetree.Name(var_name)
+            def tyvar = Splicable.Name(name)
+            def pexpr = <[$(name: name)]>
+            ParamPattern(pexpr,type_pattern.Tyvars + [tyvar], 
+                type_pattern.Constraints + [Constraint(tyvar,type_pattern.Pexpr)])
+            
+        public Array(rank:int, arg: ParamPattern): ParamPattern
+            def r = PExpr.Literal(Literal.FromInt(rank))
+            def pexpr = <[ array[$r,$(arg.Pexpr)]]>
+            ParamPattern(pexpr,arg.Tyvars,arg.Constraints)
+
+        public Arrow(from: ParamPattern, to: ParamPattern): ParamPattern
+            def pexpr = <[ $(from.Pexpr) -> $(to.Pexpr)]>
+            ParamPattern(pexpr,from.Tyvars + to.Tyvars, from.Constraints + to.Constraints)
+
+        public Tuple(args: list[ ParamPattern]): ParamPattern
+            def pes = args.Map(t=> t.Pexpr)
+            def vars = args.Map(t=> t.Tyvars)
+            def cons = args.Map(t=> t.Constraints)
+            def pexpr = <[(..$pes)]>
+            ParamPattern(pexpr, List.Flatten(vars), List.Flatten(cons))
+        
+            
     public variant TypePattern
 
         static mutable next_unique_id: int = 0

Modified: nemerle/trunk/snippets/aop/src/macros/macros.n
==============================================================================
--- nemerle/trunk/snippets/aop/src/macros/macros.n	(original)
+++ nemerle/trunk/snippets/aop/src/macros/macros.n	Tue Jul 10 17:06:06 2007
@@ -7,6 +7,7 @@
 using Nemerle.Macros
 using Nemerle.Collections
 using Nemerle.Compiler.Parsetree
+using Nemerle.Aop.Helper.ParserCombinators
 
 namespace Nemerle.Aop 
 
@@ -26,8 +27,23 @@
             unless(is_aspect(type_builder))
                 Message.Error($"$(type_builder.Name) is not an aspect")
 
-        parse_parms(parms_roundgroup: Token.RoundGroup, env: GlobalEnv): list[Fun_parm]
-            MainParser.ParseFunParms(env,parms_roundgroup)
+        parse_parms(parms_roundgroup: Token.RoundGroup, env: GlobalEnv): list[Fun_parm]*list[Splicable]*list[Constraint] {
+            def parse_parameter = 
+                parse_id <* operator(":") <*> Parse.param_pattern(_,env);
+            def parser = repetition(loosegrp(parse_parameter));
+            def lexer = Lexer(parms_roundgroup, fix=false);
+            def tokens = lexer.TokenList;
+            def result = match(parser(tokens)) {
+                | PResult.OK(val,_) => val
+                | PResult.Fail(unparsed) with description="parse failed"
+                | PResult.Error(unparsed,description) =>
+                    Message.FatalError($"$description $unparsed");
+            }
+
+            def funparms = result.Map((id,p) => <[parameter: $(id:dyn) : $(p.Pexpr)]>);
+            def ps = result.Map((_,y)=> y);
+            (funparms,List.Flatten(ps.Map(x=> x.Tyvars)), List.Flatten(ps.Map(x=> x.Constraints)))
+        }
 
         make_header(loc: Location, parms: list[Fun_parm], meth_body: ClassMember, ret_type: PExpr,typarms: Typarms): string*Fun_header
             def advice_name = Util.tmpname("advice")
@@ -91,10 +107,11 @@
             check_if_within_aspect(type_builder)
             def lexer = Lexer.WithoutFixing(tail)
             def tyvars = maybe_parse_tyvars(lexer,type_builder.GlobalEnv) 
-            def parameters = parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
+            def (parameters,artificialtyvars,constraints) = parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
             lexer.DropOperator(":")
             def (pointcut_toks,beyond_pointcut_toks) = split_tokens(lexer);
             def typarms = MainParser.ParseWhereConstraints(type_builder.GlobalEnv,beyond_pointcut_toks.Head,tyvars)
+            def typarms = Typarms(typarms.tyvars+artificialtyvars,typarms.constraints+constraints) 
             def(advice_name,header) = make_header(tail.Location, parameters, meth, PExpr.Void(), typarms)
             def advice_meth = AdviceMethod(type_builder,advice_name)
             def advice = lazy(Advice.Before(advice_meth,pointcut_toks))
@@ -105,21 +122,22 @@
             check_if_within_aspect(type_builder)
             def lexer = Lexer.WithoutFixing(tail)
             def tyvars = maybe_parse_tyvars(lexer,type_builder.GlobalEnv) 
-            def parameters = parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
-            def (after_type,ret_or_throw_parm) = match(lexer.Peek())
+            def (parameters,artificialtyvars,constraints) = parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
+            def (after_type,(ret_or_throw_parm,rtyvars,rconstrs)) = match(lexer.Peek())
                 | Token.Identifier("returning" as key) | Token.Identifier("throwing" as key) =>
                     _=lexer.Drop()
                     def ret_or_throw_parm = match(lexer.Peek())
                         | Token.RoundGroup  =>
                             parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
-                        | _ => []
+                        | _ => ([],[],[])
                     (match(key) {"returning" => AfterType.Returning | "throwing" => AfterType.Throwing | _ => throw System.Exception("expectedt returning or throwing")},ret_or_throw_parm) 
                     //TODO error when more than one return param
-                | _ => (AfterType.After,[])
+                | _ => (AfterType.After,([],[],[]))
             def has_ret_parm = ret_or_throw_parm.Length == 1
             lexer.DropOperator(":")
             def (pointcut_toks,beyond_pointcut_toks) = split_tokens(lexer);
             def typarms = MainParser.ParseWhereConstraints(type_builder.GlobalEnv,beyond_pointcut_toks.Head,tyvars)
+            def typarms = Typarms(typarms.tyvars+artificialtyvars+rtyvars,typarms.constraints+constraints+rconstrs) 
             def(advice_name,header) = make_header(tail.Location, parameters+ret_or_throw_parm, meth, PExpr.Void(), typarms)
             def advice_method = AdviceMethod(type_builder,advice_name)
             def advice = lazy(Advice.After(advice_method, pointcut_toks, has_ret_parm,after_type,ret_or_throw_parm))
@@ -140,7 +158,7 @@
             check_if_within_aspect(type_builder)
             def lexer = Lexer.WithoutFixing(tail)
             def tyvars = maybe_parse_tyvars(lexer,type_builder.GlobalEnv) 
-            def parameters = parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
+            def (parameters,artificialtyvars,constraints) = parse_parms(lexer.Pop():> Token.RoundGroup,type_builder.GlobalEnv)
             lexer.DropOperator(":")
             def ret_type = find_the_return_type(lexer)
             lexer.DropOperator(":")
@@ -161,13 +179,13 @@
                 parameters
 
             def typarms = MainParser.ParseWhereConstraints(type_builder.GlobalEnv,beyond_pointcut_toks.Head,tyvars)
+            def typarms = Typarms(typarms.tyvars+artificialtyvars,typarms.constraints+constraints) 
             def(advice_name,header) = make_header(tail.Location, parameters', meth,ret_type,typarms)
             def advice_method = AdviceMethod(type_builder,advice_name)
             def advice = lazy( Advice.Around(advice_method,pointcut_toks) )
             define_advice_member(beyond_pointcut_toks.Head,type_builder,header,tail.Location)
             advice
 
-    
     [Nemerle.MacroUsage(Nemerle.MacroPhase.BeforeInheritance,
                        Nemerle.MacroTargets.Method)]\
     macro before( type_builder: TypeBuilder, advice: ParsedMethod, tail: Token )\



More information about the svn mailing list