EN JP CN

Java KAST 例

Java KAST 例
In this topic:

Java KAST 例

Java KAST 例

次の例で、一般的な Java KAST 式を説明します。

括弧が多すぎる式

// ExprBrackets / Expr::{ ExprBrackets/Expr::} ExprBrackets

class Foo {
   int x = 2;
   int y = ((x + 1)) / 2;
   int z = (((i - 1))) * 2;
}
注: 子 AST ノードのチェーンに一致させるためには、"0 以上の子のシーケンス" 修飾子 ({}) を使用してください。

戻り値の型がプリミティブのすべてのメソッドを検索する

// MethodDecl [ Type::PrimitiveType ]

class Foo {}

class Bar {
// no match - returns reference
   Foo foobar() {
      return new Foo();
   }

// finds this
   int intbar() {
      return 0;
   }
}

戻り値の型がプリミティブ型ではないすべてのメソッドを検索する

// MethodDecl [ not Type::PrimitiveType ]

class Foo {}

class Bar {
// finds this
   Foo foobar() {
      return new Foo();
   }

// but not this
   int intbar() {
      return 0;
   }
}
注: 述部の結果を否定するには、not 演算子を使用してください。

すべての void メソッドを検索する

// MethodDecl [ Type::VoidType ]

>class Bar {
// finds this
   void voidbar() {}

// but not this
   int intbar() {
      return 0;
   }
}

すべての静的メソッドを検索する

// 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;
   }
}

インスタンス初期化子を含むすべてのクラスを検索する

// 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;
      }
   }
}
注: AST ノードのシーケンスに指定されたタイプのノードが含まれる場合は、"任意の要素" 修飾子 ([*]) を使用してください。

クラス/インターフェイス/列挙/注釈に属さないすべての注釈宣言を検索する

// 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 {} 
}

すべてのメンバー注釈宣言を検索する

// 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 {} 
}

ブロックが関連付けられていない列挙定数のすべての宣言を検索する

// 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;
      }
}
注: AST ノードの欠落した子を示すには、Null を使用してください。

関連するブロックにメソッド宣言を持つが、初期化引数は持たないすべての列挙定数を検索する

// 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;
      }
}

すべての接頭辞増分式を検索する

// ExprPrefix [ @Op = OP_INC ]

public class Foo {
   void bar() {
      int i = 0;
      int j = ++i;
   }
}

式を lvalue として型指定する

// ExprBinary [ @Op = OP_ASSIGN ] / Expr1::ExprCast

public class Foo {
   double d;
   void bar() {
      (int)d = 3;
   }
}

名前が大文字で始まらないすべてのクラスを検索する

// 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 {
   };
};

名前が "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;
}

後に '}' が配置されている switch ラベル (空の switch ケース) を検索する

// SwitchGroup [ Stats::Null ]

class Foo {
   void mymethod(int f) {
      switch (f) {
         case 1: /* empty switch case will be matched here */
      }
   }
}
注: 空の子のリストを示すには、Null を使用してください。

定数の switch セレクターの検索

// 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;
      }
   }
}

このチェッカーの要点は、定数が使用されている場合を検索することですが、列挙型の値を使用する方が効果的です。

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 {
         ...
      }
   }
}

ELSE ブランチのあるすべての IF ステートメントを検索する

//IfElseStat

class Foo {
   void mymethod(boolean b) {
      if (b) {  // do not match this one
         ...
      } 
      if (b) {  // match this one
         ...
      } else {
         ...
      }
   }
}

少なくとも 1 つの実行可能ステートメントを含む複合ステートメントである ELSE ブランチを持つ IF ステートメントを検索する

// 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
      }
   }
}

バイナリ "+" 演算を検索する

// ExprBinary / [@Op = OP_PLUS ]

class Foo {
   c = 1 / 2; // do not match
   int x = 1 + c; // match this one
}

任意のクラスの '不審な' メソッドの呼び出しを検索する

// 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();

   }
}

'void' または '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();
   }
}