Java KAST examplesJava KAST examplesThe following examples describe common Java KAST expressions. Overparenthesized expression// ExprBrackets / Expr:: { ExprBrackets/Expr:: } ExprBrackets class Foo { int x = 2; int y = ((x + 1)) / 2; int z = (((i - 1))) * 2; } Note: Use "sequence of 0 or more children" modifier ({}) to match a chain of child AST nodes.
Find all methods whose return type is a primitive one// MethodDecl [ Type::PrimitiveType ] class Foo {} class Bar { // no match - returns reference Foo foobar() { return new Foo(); } // finds this int intbar() { return 0; } } Find all methods whose return type is not a primitive type// MethodDecl [ not Type::PrimitiveType ] class Foo {} class Bar { // finds this Foo foobar() { return new Foo(); } // but not this int intbar() { return 0; } } Note: Use not operator to negate the result of predicate.
Find all void methods// MethodDecl [ Type::VoidType ] >class Bar { // finds this void voidbar() {} // but not this int intbar() { return 0; } } Find all static methods// MethodDecl [ isStatic() ] class Foo {} class Bar { // finds this static Foo foobar() { return new Foo(); } // and this public final static void voidbar() {} // no match - not static int intbar() { return 0; } } Find all classes that contain instance initializers// ClassDecl [ ClassBody::ClassOrInterfaceBody / ClassOrInterfaceBodyDecls[*]::InstanceInitializer ] // no match - does not have instance initializer public class Container { // finds this class public class Example1 { private int i; { i = 0; } } // but not this one - this class has static initializer but no instance initializer public class Example2 { private int j; static { j = 0; } } } Note: Use "any element" modifier ([*]) to check if a sequence of AST nodes contains a node of specified type.
Find all annotation declarations that don't belong to any class/interface/enum/annotation// AnnotationDecl [ not ancestor::ClassOrInterfaceBody ] // finds this one public @interface Preliminary { } @Preliminary public class Foo { // no match - member annotation declaration private @interface Inner {} @Inner private interface Bar {} } Find all member annotation declarations// InnerAnnotationDecl / InnerAnnotationDecl::AnnotationDecl // no match - not a class/interface/enum/annotation member public @interface Preliminary { } @Preliminary public class Foo { // finds this one private @interface Inner {} @Inner private interface Bar {} } Find all declaration of enum constants that don't have associated blocks// EnumConstDecl [ EnumConstBlock::Null ] public enum Modifiers { // finds this one PUBLIC(1), // no match - has an associated block STATIC(2) { public int foo() { return 2; } }, // finds this one FINAL; private int id; public int foo() { return 0; } } Note: Use Null to indicate a missing child of an AST node.
Find all enum constants that have method declarations in associated blocks but no initialization arguments// MethodDecl / parent::ClassOrInterfaceBody / parent::EnumConstDecl [ Arguments::Null ] public enum Modifiers { // no match - no methods in associated block PUBLIC { }, // finds this one STATIC { public int foo() { return 2; } }, // no match - no associated block FINAL, // no match - has an argument PROTECTED(4) { public int foo() { return 4; } }; private int id; public int foo() { return 0; } } Find all prefix incremental expressions// ExprPrefix [ @Op = OP_INC ] public class Foo { void bar() { int i = 0; int j = ++i; } } Cast expression as lvalue// ExprBinary [ @Op = OP_ASSIGN ] / Expr1::ExprCast public class Foo { double d; void bar() { (int)d = 3; } } Find all classes whose name does not start with uppercase letter// ClassDecl [ not getName().starts-from-capital() ] // finds this class public class foo { // and this one private class boo {} // no match - starts with upper-case letter public class Moo {} } class A { }; class b { }; struct C { // and this union union x { }; }; Find all non-public class fields, whose name does not start with "m_"// FieldDecl / Declrs[*]::* [ not isPublic() ] [ not getName().starts-with('m_') ] public class Foo { // no match - starts with 'm_' static int m_count; // no match - public member public static char symbol; // no match - starts with 'm_' protected int m_foo; // finds this field private final boolean flag = false; } Find switch labels followed by '}' (empty switch cases)// SwitchGroup [ Stats::Null ] class Foo { void mymethod(int f) { switch (f) { case 1: /* empty switch case will be matched here */ } } } Note: Use Null to indicate an empty child list.
Find switch selector that is constant// SwitchLabel1 / Expr::ExprLiteral class Foo { void bar() {} void baz() {} void mymethod(int f) { switch (f) { case 1: bar(); /* constant is used for a selector */ break; default: baz; } } } The point of this checker is to find places where constant is used, but it is better to use the value of enumerated type. Find all IF statements without ELSE branch//IfStat class Foo { void mymethod(boolean b) { if (b) { // match this one ... } if (b) { // do not match this one ... } else { ... } } } Find all IF statements with ELSE branch//IfElseStat class Foo { void mymethod(boolean b) { if (b) { // do not match this one ... } if (b) { // match this one ... } else { ... } } } Find IF statements whose ELSE branch is a compound statement containing at least one executable statement// IfElseStat / ElseStat::BlockStat [ Stats[*]::ExprStat ] class Foo { void mymethod(boolean b) { if (b) { printf("IfStatement"); } else printf("IfStatement: Else"); // do not match this one if (b) { printf("IfStatement: Then"); } else { printf("IfStatement: Else"); // match this one } if (b) { printf("IfStatement"); } else { /* code */ // do not match this one } } } Find binary "+" operations// ExprBinary / [@Op = OP_PLUS ] class Foo { c = 1 / 2; // do not match int x = 1 + c; // match this one } Find calls to 'suspicious' method of any class// ExprCall [ Expr::ExprField [ @Id = 'suspicious' ] | Expr::ExprName [ getName() = 'suspicious' ] ] class Bar { class Foo { public int suspicious() { return 0; } } char suspicious() { return '\0'; } int good() { return 1; } void foo() { // no match - not 'suspicious' method int x = good(); // finds this char y = suspicious(); // and this int z = new Foo().suspicious(); } } Find declarations of methods that return 'void' or 'char'// MethodDecl [ Type::PrimitiveType [ @Type = PT_CHAR ] | Type::VoidType ] class Bar { class Foo {} // finds this public final static void voidbar() {} // and this char charbar() { return 0; } // no match - returns neither void nor char Foo foobar() { return new Foo(); } } |