Software Engineering for Smart Data Analytics & Smart Data Analytics for Software Engineering

User Tools

Site Tools


This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
research:logicaj:pointcuts [2008/05/27 15:43]
research:logicaj:pointcuts [2018/05/09 01:59] (current)
Line 1: Line 1:
 +====== LogicAJ Pointcuts ======
 +===== Logic Meta-Variables =====
 +The main distinction between LogicAJ and AspectJ is LogicAJ'​s concept of logic meta-variables: ​
 +  * A //logic meta-variable//​ (//LMV//) is a metavariable that matches //one// base language element (e.g. a field access). Syntactically,​ it is an identifier with a prepended question mark: **LMV** ::​=**?​**//​Identifier//​
 +  * A //logic list meta-variable//​ (//LLMV//) is a metavariable that matches //a list of// base langauge elements (e.g. a parameter list). Syntactically,​ it is an identifier with two prepended question marks: **LLMV** ::​=**??​**//​Identifier//​
 +Meta-variables are like named wildcards. Unlike with wildcards, one can refer to the value matched by a meta-variable by using the same meta-variable in another expression within the same scope. All occurrences of the same meta-variable in a scope must match the same value.
 +If a meta-variable occurs only once in a scope it can be replaced by the //"​anonymous"​ metavariable//,​ whose name is the underscore: "''​**?​_**''"​. ​ Every occurrence of the anonymous meta-variable is considered to be a different meta-variable (matches of the anonymous metavariable do not
 +need to agree on the matched value). The underscore can also be used as an //anonymous list meta-variable//,​ "''​**??​_**''"​.
 +Anonymous meta-variables are the equivlent of simple wildcards. "''?​_''"​ is equivalent to "''​*''"​ and "''??​_''"​ is equivalent to "''​..''"​.
 +Although meta-variables subsume wildcards, the AspectJ-like wildcard syntax is supported in LogicAJ for backward compatibility and for the convenience of former AspectJ programmers. ​
 +Syntactically,​ both kinds of meta-variables are identifiers with prepended question marks:
 +**LMV** ::=**?** //​Identifier//​\\
 +**LLMV** ::=**??** //​Identifier//​
 +==== Valid Bindings ====
 +A "​binding"​ is a value for a meta-variable. Valid (component) types for meta-variables bindings are:
 +  * string - String literals ("​value"​)
 +  * float - float values
 +  * int - integer values
 +  * identifier - a Java identifier
 +  * type - fully qualified names (e.g. java.lang.Object)
 +  * param - method parameters (e.g. ??params in method( ?_ ?​type.??​params(..))
 +  * expr - expressions (e.g. ??args in args(??​args) )
 +Checking the type of meta-variables is done at weave-time, not at compile-time of individual aspects. So you will get weaving errors if e.g. a variable of type identifier is used in an arithmetic expression. However, you will never get run-time exceptions because of wrong types, as would be the case if you used reflection.
 +Compile-time checking of meta-variable types will be part of a future release. ​
 +You may use fully qualified names, identifiers or strings where a value of type //type// is expected and vice versa. The value will be automatically converted, e.g.:
 +  type(?​stringType) &&
 +  equals(?​stringType,​ java.lang.String)
 +is equivalent to
 +  equals(?​stringType,​ "​java.lang.String"​)
 +Also an automatic conversion is attempted for string values used in arithmetic expressions. ​
 +Of course, this will result in a weaving error if the value can not be converted.
 +==== Patterns with Metavariables ====
 +Meta-variables and list meta-variables can be used in advice, introductions and the patterns of pointcuts. In patterns, they can be used (at least) wherever wildcards (*, **, or ..) can be used in AspectJ:
 +<table width="​100%" ​ border="​0">​
 +  <tr>
 +    <td colspan="​2"><​i>​MethodPat</​i>​ ::​=<​br/>​
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;​ [ <​i>​ModifiersPat</​i>​ ] <​i>​TypePat TypePat</​i>​ <​b>​.</​b>​ <​i>​NamePat</​i>​ <​b>​(</​b>​ [ <​i>​ArgOrParamListPat</​i>​ ] <​b>​)</​b>​ [ <​b>​throws </​b><​i>​TypeListPat</​i>​ ]<​br/>​
 +<​i>​FieldPat</​i>​ ::​=<​br/>​
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;​ [ <​i>​ModifiersPat </i>] <​i>​TypePat TypePat</​i>​ <​b>​.</​b>​ <​i>​NamePat </​i></​td>​
 +  </tr>
 +  <tr valign="​top">​
 +    <td width="​36%"><​i>​TypeListPat </​i>::<​i>​=<​br />
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;</​i><​i><​em>​ </​em>​TypePat </​i>​(<​i>​ <​strong>,</​strong>​ </​i><​i>​TypePat</​i>​)*<​i><​br />
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;​ ( <​i>​NamePat</​i>​ <​b>​.</​b>​ )* <​i>​NamePat</​i>​ ( <​b>​[]</​b>​ )*<​br/>​
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;​|&​nbsp;​ <​b>​!</​b>​ <​i>​TypePat</​i>​ <br/>
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;​|&​nbsp;​ <​i>​TypePat</​i>​ <​b>&​amp;&​amp;</​b>​ <​i>​TypePat</​i>​ <br/>
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;​|&​nbsp;​ <​i>​TypePat</​i>​ <​b>​||</​b>​ <​i>​TypePat</​i>​ <br/>
 +<​i>​ArgOrParamListPat </​i>::<​i>​=<​br />
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;</​i><​i><​em>​ </​em>​ArgOrParamPat </​i>​(<​i>​ <​strong>,</​strong>​ </​i><​i>​ ArgOrParamPat </i>) *<​i><​br />
 +ArgOrParamPat </​i>::<​i>​=<​br />
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;​TypePat</​i>​ <br />
 +<​i>&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;</​i>​| <​em>​AdviceParamName</​em><​br />
 +<​i>&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;</​i>​| <​b>​..<​br />
 +<​i>&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;</​i></​b>​| <i> <​u>​LLMV</​u></​i><​i></​i></​td>​
 +    <td width="​64%"><​em>​AdviceParamName </​em>::<​i>​=</​i><​br />
 +      <​i>&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;</​i><​em>​Identifier</​em><​br/>​
 +      <​i>​NamePat</​i>​ ::=<br />
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;​ <i> <​u>​LMV</​u>​ </i> <​i><​br />
 +&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​ | </i> <i> </i>( *| \? | <​i>​Identifier</​i>​ )+<br />
 +<​i>​ModifiersPat</​i>::​=<​br />
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;​ <i> <​u>​LLMV</​u>​ </i> <​i><​br />
 +&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​ | </i>( [ <​strong>​!</​strong><​span>​ ]</​span><​i><​span>​ Modifier </​span>​ </​i>​)+<​br />
 +<​i>​Modifier</​i>::​=<​br />
 +&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;​ <​strong>​ public </​strong>​ <​i><​br />
 +&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​ | </​i><​strong>​protected<​br />
 +<​i>&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​i></​strong>​ ... <br />
 +<​i>&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​ |</i> <​strong>​volatile</​strong>​ </td>
 +  </tr>
 +===== Pointcuts Documentation =====
 +Below, the type of an argument is postfixed to the argument name separated by a colon.
 +If the type is omitted arbitrary meta-variable types can be used.
 +See also the the [[#Valid Bindings]] paragraph above.
 +  <link href="​http://​​research/​logicaj/​downloads/​pcstyle.css"​ type="​text/​css"​ rel="​stylesheet">​
 +<​body><​h2 class="​category">​Selective Pointcuts With Metavariables</​h2>​
 +<table class="​syntax"><​tbody><​tr><​td width="​2"​ /><td class="​title"​ width="​400">​General Syntax</​td><​td class="​title">​Examples</​td><​td width="​2"/></​tr></​tbody>​
 +  <​tbody><​tr><​td/><​td class="​subcategory"​ rowspan="​1"​ colspan="​2"></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​call(MethodPat|ConstructorPat)</​td><​td><​b>​call</​b>​ ( void Foo.m(int) )</​br> ​   a call to the method void Foo.m(int)</​br>​ <​b>​call</​b>​ ( )</​br> ​   a call to any constructor of Foo</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​execution(MethodPat|ConstructorPat)</​td><​td>​execution ( * Foo.*(..) throws IOException ) </​br> ​  the execution of any method of Foo that is declared to throw IOException</​br>​ execution ( !public Foo .new(..) )</​br>​ the execution of any non-public constructor of Foo</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​withincode(MethodPat|ConstructorPat)</​td><​td><​b>​withincode</​b>​ ( void Figure.move() )</​br> ​  any join point where the associated code is defined in the method void Figure.move()</​br></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​get(FieldPat)</​td><​td><​b>​get</​b>​ ( int Point.x ) </br> when int Point.x is read</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​set(FieldPat)</​td><​td><​b>​set</​b>​ ( !private * Point.* ) </br> when any field of Point is assigned</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​within(TypePat)</​td><​td><​b>​within</​b>​( com.bigboxco.* )</​br>​ any join point where the associated code is defined in the package com.bigboxco</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​target(TypePat | Var)</​td><​td><​b>​target</​b>​( ) </​br>​any join point where the target (receiver) object is an instance of</​br>​ The target pointcut can also be used to bind advice parameters: after(Object o) : call(..) && target(o) {...}</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​this(TypePat | Var)</​td><​td><​b>​this</​b>​( Point )</​br>​any join point where the currently executing object is an instance of Point</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​args(ArgsPat)</​td><​td><​b>​args</​b>​(,​ int )any join point where there are two arguments, </​br> ​  the first an  instance of,​ and the second an int </p> <​b>​args</​b>​( *, int ) </​br> ​  any join point where there are two arguments, </​br> ​  the second of  which is an int. </​p><​b>​args</​b>​( short, .., short ) </​br> ​  any join point with at least two arguments, the first and last of which are shorts</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​receiverIsThis()</​td><​td>​checks that the receiver of the join point is this</​td><​td/></​tr>​
 +  </​tbody>​
 +<h2 class="​category">​Predicate Pointcuts</​h2>​
 +<table class="​syntax"><​tbody><​tr><​td width="​2"​ /><td class="​title"​ width="​400">​General Syntax</​td><​td class="​title">​Examples</​td><​td width="​2"/></​tr></​tbody>​
 +  <​tbody><​tr><​td/><​td class="​subcategory"​ rowspan="​1"​ colspan="​2"></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​equals( Arg1, Arg2)</​td><​td>​Checks if first and second argument equal</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​jointPoint(Arg:​string)</​td><​td></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​constructName(Name:​string)</​td><​td></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​replace(?​String:​string,?​SearchCharacter:​string,?​ReplaceCharacter:​string,?​Result:​string)</​td><​td>​e.g. replace("​asdf","​s","​f","​afdf"</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​var(?​var)</​td><​td>​Checks if ?var is not bound.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​debug(Message:​string,​ ?​lmv1:​lmv,​...)</​td><​td>​Generates trace data for the current pointcut definition, see also <a href="​https://​​research/​logicaj/​debugging>">​Pointcut Debugging</​a></​td><​td/></​tr>​
 +  </​tbody>​
 +  <​tbody><​tr><​td/><​td class="​subcategory"​ rowspan="​1"​ colspan="​2">​Class Member</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​method(MethodPat)</​td><​td>​selects matching methods and binds meta-variables in the pattern; the optional <​i>​LMV</​i>​ binds the body of the method, e.g:<​br>​ </​span><​span><​span style="​font-weight:​ bold;">​method</​span>​ ( void Foo.?m(int) )<br> &nbsp; &nbsp; selects all method in the type <span style="​font-style:​ italic;">​Foo</​span>​ with return type&​nbsp;<​span style="​font-style:​ italic;">​void&​nbsp;</​span>​and <span style="​font-style:​ italic;">​int</​span>​ parameter;<​br>​ &nbsp; &nbsp; all method names are bound to ?​m</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​field(FieldPat)</​td><​td>​selects matching fields and binds meta-variables in the pattern; the optional <​i>​LMV</​i>​ binds the initializer of the field</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​directsubtype(Subtype:​type,​ Supertype:​type)</​td><​td>​binds <​b>​Subtype</​b>​ to direct subtype of the second argument <​b>​Supertype</​b></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​subtype(Subtype:​type,​ Supertype:​type)</​td><​td>​binds <​b>​Subtype</​b>​ to all subtypes (interfaces or classes) of the second argument <​b>​Supertype</​b></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​inner(InnerClass:​type)</​td><​td>​binds <​b>​InnerClass</​b>​ to inner classes</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​local(LocalClass:​type)</​td><​td>​binds <​b>​LocalClass</​b>​ to local classes~n e.g. void m() { class C { ...}; }</​td><​td/></​tr>​
 +  </​tbody>​
 +  <​tbody><​tr><​td/><​td class="​subcategory"​ rowspan="​1"​ colspan="​2">​String Literal</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​subString(?​String:​string,​ ?Start:int, ?​Length:​int,​ ?After:int, ?​Sub:​string)</​td><​td>​ substring maintains the  following relation:​Sub is  a sub-string of Str that starts at Before, has Len characters and Str contains After characters after the match.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​camelCase(?​Identifier:​identifier,​ ?​CamelCaseIdentifier:​identifier)</​td><​td>​example:​ camelCase(myField,​MyField)</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​upperCase(?​AnyCase:​string,​ ?​UpperCase:​string)</​td><​td>​Converts the characters of ?AnyCase into upper case and binds the string to ?​UpperCase.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​lowerCase(?​AnyCase:​string,​ ?​LowerCase:​string)</​td><​td>​Converts ​ the characters of AnyCase ​ into lower case and binds the string to LowerCase. </​td><​td/></​tr>​
 +    <​tr><​td/><​td>​stringToCharacters(?​String,??​Characters)</​td><​td>​Converts between a ?String and and a list of ??​Characters. Characters are Strings of length one.</​td><​td/></​tr>​
 +  </​tbody>​
 +  <​tbody><​tr><​td/><​td class="​subcategory"​ rowspan="​1"​ colspan="​2">​List</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​member(Member,​List:​list)</​td><​td>​Checks if the first argument is a member of the list bound to the second argument; the second argument must already be bound</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​length(List:​list,​Int:​int)</​td><​td>​Succeeds if Int represents the number of elements of list List.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​outer(Inner:​type,​ Outer:​type)</​td><​td>​Binds <​i>​Outer</​i>​ to the outer class of an inner/​local/​anonymous class</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​split(?​Head,​ ??​TailList:​list,​ ??​List:​list)</​td><​td>​Separates ??List in the ?Head element and the Tail of the list. Tail can be an empty list.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​concat(Arg1:​string,​ Arg2:​string,​ Arg3:​string)</​td><​td>​The third Arg forms the concatenation of the first and the second Arg</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​concat(Arg1:​string,​ Arg2:​string,​ Arg3:​string,​ Arg4:​string)</​td><​td>​Arg4 forms the concatenation of Arg1,​..,​Arg3</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​concat(Arg1:​string,​ Arg2:​string,​ Arg3:​string,​ Arg4:​string,​ Arg5:​string)</​td><​td>​Arg5 forms the concatenation of Arg1,​..,​Arg4</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​removeElements(??​RemoveElements:​list,​ ??​FromList:​list,​ ??​ResultList:​list)</​td><​td>​Removes ??​RemoveElements from ??FromList and binds the resulting list to ??​ResultList.</​td><​td/></​tr>​
 +  </​tbody>​
 +  <​tbody><​tr><​td/><​td class="​subcategory"​ rowspan="​1"​ colspan="​2">​Types</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​concreteAspect(?​Type:​type)</​td><​td>​Bind ?Type to the enclosing concrete aspect'​s class.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​ pattern( Arg, RegEx:​string [, groupX:​string] )</​td><​td>​Checks if the pattern RegEx matches the first argument. <p> E.g. pattern("​bbacc","​(.*)a(.*)",?​Match1,​ "​cc"​) where ?Match1 matches the first group ("​aa"​).</​p>​ <​p><​b>​Be aware:</​b>​ Shorthand characters like \w do not work. Use [a-z] etc. instead.</​p><​p>​For details on the RegEx flavour see also the last paragraph of the <a href="​http://​​8080/​class?​name=regex">​SWI-Prolog RegEx</​a>​ documentation.</​p></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​types(??​Elements:​list,​ ??​Types:​list<​type>​)</​td><​td>​Unifies <​i>??​Types</​i>​ with the list of types of <​i>??​Elements</​i>,​ where Elements may contain parameter declarations or argument expressions</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​package(?​Package:​string)</​td><​td>​Unifies ?Package with the packages defined in the project</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​sourcetype(PType:​type)</​td><​td>​Checks if <​i>​Type</​i>​ is available in source code. Otherwise it was read from a library (as byte code). This is important since LogicAJ only weaves aspects into source classes.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​typename(?​Type:​type,?​SimpleTypeName:​string)</​td><​td>​binds the type name of ?Type to ?​SimpleTypeName</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​typepackage(?​Type:​type,?​PackageName:​string)</​td><​td>​binds the package name of ?Type to ?​PackageName</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​packagetolist(?​Package:​string,??​PackageNames:​list<​string>​)</​td><​td>​e.g. packagetolist("​org.cs3",​ ["​org","​cs3"​])</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​arrayType(?​ComponentType:​type,​ ?Arity:int, ?​Type:​type)</​td><​td>​e.g. arrayType("​java.lang.Object[]",​1,​ "​java.lang.Object[]"​)</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​aspect(?​Type:​type)</​td><​td>​check if ?Type is an aspect class</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​type(?​Type:​type)</​td><​td>​selects matching types and binds meta-variables in the pattern, e.g.:  ​
 + </​br><​b>​type</​b>​(?​type) or
 + </​br><​b>​type</​b>​(?​packagename.?​name) ​
 + </​br>​binds ?package to the complete package name of the package of all types and ?name to the name of the type 
 + </​br><​b>​notice</​b>:</​br>​in future ?​packagename will only bind package name parts without dots, e.g. pack1;lists of (sub-)package names may be bound with ??​package,</​br>​e.g. type(??​prefix.?​api.internal.??​rest.?​classname)</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​class(?​Class:​type)</​td><​td>​like type(..), but ensures that TypePat is a class</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​interface(?​Interface:​type)</​td><​td>​Checks if ?Interface is an interface.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​enum(?​Enumeration:​type)</​td><​td>​Checks if ?​Enumeration is an enumeraration.</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​annotationType(?​Annotation:​type)</​td><​td>​Checks if ?Annotation is an annotation type.</​td><​td/></​tr>​
 +  </​tbody>​
 +  <​tbody><​tr><​td/><​td class="​subcategory"​ rowspan="​1"​ colspan="​2">​Arithmetic</​td><​td/></​tr>​
 +    <​tr><​td/><​td>​lt(Number1:​int,​Number2:​int)</​td><​td>​True if <​i>​Number1</​i>​ is smaller than <​i>​Number2</​i></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​le(Number1:​int,​Number2:​int)</​td><​td>​True if <​i>​Number1</​i>​ is smaller or equal to <​i>​Number2</​i></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​gt(Number1:​int,​ Number2:​int)</​td><​td>​True if <​i>​Number1</​i>​ is greater than <​i>​Number2</​i></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​ge(Number1:​int,​ Number2:​int)</​td><​td>​True if <​i>​Number1</​i>​ is greater or equal to <​i>​Number2</​i></​td><​td/></​tr>​
 +    <​tr><​td/><​td>​ge(Number1:​int,​ Number2:​int,​Sum:​int)</​td><​td>​True if <​i>​Sum</​i>​=<​i>​Number1</​i>​+<​i>​Number2</​i>​. At least two  of the  three arguments must be instantiated to integers.</​td><​td/></​tr>​
 +  </​tbody>​
research/logicaj/pointcuts.txt · Last modified: 2018/05/09 01:59 (external edit)

SEWiki, © 2019