| 说明:通用属性为所有节点都有的属性 | 
| 属性 | 描述 | 值类型 | 示例 | DSL 规则 | 
| annotations | 节点的注解 | annotation节点集合 | @Parameter(names = {"ok", "hello", "yes"})public void initArrayTest() {}
 | functionDeclaration fd where fd.annotations contain anno where
 anno.name == "Parameter";
 | 
| startLine | 节点的起始行 | 数值 | _ | functionDeclaration fd where fd.startLine == 21;
 | 
| endLine | 节点的结束行 | 数值 | _ | functionDeclaration fd where fd.endLine == 23;
 | 
| enclosingClass | 节点所在的类 | recordDeclaration节点 | public class FunctionCallTest {public void setHeader(String header, String option) {
 new MyRandom().intNum();
 }
 
 public String getString(String ok, String ss) {
 return ss;
 }
 
 public void getIt() {
 setHeader("Access-Control-Allow-Origin", "*");
 }
 }
 | functionCall fc where and(fc.function.name == "setHeader",
 fc.function.enclosingClass.name endWith "FunctionCallTest"
 );
 | 
| enclosingClassName | 节点所在的类名 | 字符串 | new MyRandom().intNum(); | functionCall fc where and(fc.name == "intNum",
 fc.function.enclosingClassName endWith "MyRandom"
 );
 | 
| enclosingFunction | 节点所在的方法 | functionDeclaration节点 | public String getString(String ok, String ss) {return ss.replace('1', '2');
 }
 | functionCall fc where and(fc.name == "replace",
 fc.enclosingFunction.parameters.size() == 2
 );
 | 
| enclosingFunctionName | 节点所在的方法名 | 字符串 | public String getString(String ok, String ss) {return ss.replace('1', '2');
 }
 | functionCall fc where and(fc.name == "replace",
 fc.enclosingFunctionName == "getString"
 );
 | 
| enclosingIf | 节点所在的If块 | ifBlock节点 | private void testEnclosingIf() {boolean flag = true;
 if(!flag) {
 int n = 0;
 System.out.println(n);
 while (n < 5) {
 if (flag) {
 System.out.println("ifBlock2"); // 告警行
 n++;
 }
 }
 }
 }
 | functionCall fc5 where and(fc5.enclosingFunction.name == "testEnclosingIf",
 fc5.name == "println",
 fc5.enclosingIf.startLine == 117
 );
 | 
| enclosingFor | 节点所在的for循环 | forBlock节点 | private void testEnclosingFor() {int rows = 5;
 int columns = 10;
 
 for (int i = 0; i < rows; i++) {
 int count = 0;
 count++;
 for (int j = 0; j < columns; j++) {
 if (j % 2 == 0){
 count++; // 告警行
 }
 }
 }
 }
 | unaryOperation uo1 where and(uo1.enclosingWhile.size() == 0,
 uo1.enclosingTry.size() == 0,
 uo1.enclosingCatch.size() == 0,
 uo1.enclosingForEach.size() == 0,
 uo1.enclosingFunction.name == "testEnclosingFor",
 uo1.operand.name == "count",
 uo1.enclosingFor.startLine == 30
 );
 | 
| enclosingForEach | 节点所在的forEach循环 | forEachBlock节点 | private void testEnclosingForEach() {List<List<Integer>> numbers = new ArrayList<>();
 numbers.add(Arrays.asList(1, 2, 3));
 numbers.add(Arrays.asList(4, 5, 6));
 numbers.add(Arrays.asList(7, 8, 9));
 
 for (List<Integer> row : numbers) {
 for (int num : row) {
 System.out.println(num + " "); // 告警行
 }
 System.out.println();
 }
 }
 | functionCall fc1 where and(fc1.enclosingFunction.name == "testEnclosingForEach",
 fc1.name == "println",
 fc1.enclosingForEach.startLine == 47
 );
 | 
| enclosingWhile | 节点所在的while循环 | whileBlock节点 | private void testEnclosingWhile() {int rows = 4;
 int columns = 6;
 int i = 0;
 
 while (i < rows) {
 int j = 0;
 while (j < columns) {
 System.out.println("* "); // 告警行
 j++;
 }
 System.out.println();
 i++;
 }
 }
 | functionCall fc2 where and(fc2.enclosingFunction.name == "testEnclosingWhile",
 fc2.name == "println",
 fc2.enclosingWhile.startLine == 62
 );
 | 
| enclosingTry | 节点所在的try块 | tryBlock节点 | private void testEnclosingTry() {try (FileInputStream fileInputStream = new FileInputStream("file.txt")) {
 try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream))) {
 String line;
 while ((line = bufferedReader.readLine()) != null) {
 System.out.println(line);
 }
 } catch (IOException e) {
 System.out.print("Error reading file: " + e.getMessage()); // 告警行
 }
 } catch (IOException e) {
 System.out.println("File not found: " + e.getMessage());
 }
 }
 | functionCall fc3 where and(fc3.enclosingFunction.name == "testEnclosingTry",
 fc3.name == "print",
 fc3.enclosingTry contain variableDeclaration
 );
 | 
| enclosingCatch | 节点所在的catch块 | catchBlock节点 | private void testEnclosingCatch() {try {
 int[] arr = new int[5];
 arr[10] = 20;
 String str = null;
 System.out.println(str.length());
 } catch (ArrayIndexOutOfBoundsException e) {
 System.out.println("数组越界异常:" + e.getMessage());
 } catch (NullPointerException e) {
 System.out.println("空指针异常:" + e.getMessage());
 } catch (Exception e) {
 if (e instanceof IOException) {
 System.out.println("IO异常:" + e.getMessage()); // 告警行
 } else {
 System.out.println("其他异常:" + e.getMessage()); // 告警行
 }
 } finally {
 System.out.println("程序执行完毕!");
 }
 }
 | functionCall fc4 where and(fc4.enclosingFunction.name == "testEnclosingCatch",
 fc4.name == "println",
 fc4.enclosingCatch.startLine == 98
 );
 | 
 
评论(0)