2017-09-13 80 views
1

我想将Java方法名称与正则表达式匹配,但我不确定如何在Rascal中执行此操作。我想匹配名称以test(例如JUnit 3测试用例)开头的方法,并将其转换为JUnit 4测试用例,并使用@Test注释和删除前缀test。我的代码如下所示:将声明的方法名称与正则表达式匹配

public tuple[int, CompilationUnit] refactorJUnitTestCaseDeclaration(CompilationUnit cu) { 
    int total = 0; 
    println(cu); 

    CompilationUnit unit = visit(cu) { 
      case(MethodDeclaration)`public void <Identifier name>() <MethodBody body>`: { 
      if(/test[A-Z]*/ := name) { 
       total += 1; 
       newName = name[4..]; 
       insert (MethodDeclaration)`@Test public void <Identifier newName>() <MethodBody body>`; 
      }; 
     } 
    }; 
    return <total, unit>; 
} 

该代码产生以下错误:

Expected str, but got Identifier 

有什么办法来访问name方法标识符为字符串,所以我可以尝试搭配呢?如果没有,完成这个任务的最好方法是什么?

回答

1
  • 的正则表达式模式运营商想只能匹配字符串,所以你要的name解析树(这是类型的标识符)映射到一个字符串,像这样:"<name>"
  • 同样,要将新名称字符串拼接回标识符的位置,您必须将其映射回标识符,如下所示:[Identifier] newName

最终的结果看起来是这样的:

public tuple[int, CompilationUnit] refactorJUnitTestCaseDeclaration(CompilationUnit cu) { 
    int total = 0; 
    println(cu); 

    CompilationUnit unit = visit(cu) { 
      case(MethodDeclaration)`public void <Identifier name>() <MethodBody body>`: { 
      if(/test[A-Z]*/ := "<name>") { 
       total += 1; 
       newName = [Identifier] "<name>"[4..]; 
       insert (MethodDeclaration)`@Test public void <Identifier newName>() <MethodBody body>`; 
      }; 
     } 
    }; 
    return <total, unit>; 
} 

您也可以直接尾部匹配出与一组命名:

public tuple[int, CompilationUnit] refactorJUnitTestCaseDeclaration(CompilationUnit cu) { 
    int total = 0; 
    println(cu); 

    CompilationUnit unit = visit(cu) { 
      case(MethodDeclaration)`public void <Identifier name>() <MethodBody body>`: { 
      if(/test<rest:[A-Z]*>/ := "<name>") { 
       total += 1; 
       newName = [Identifier] rest; 
       insert (MethodDeclaration)`@Test public void <Identifier newName>() <MethodBody body>`; 
      }; 
     } 
    }; 
    return <total, unit>; 
} 
+0

它的工作太棒了!谢谢! – urielSilva