[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