将声明的方法名称与正则表达式匹配

时间:2017-09-13 01:10:26

标签: rascal

我正在尝试将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

有没有办法以{String}身份访问name方法标识符,所以我可以尝试匹配它?如果没有,最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

  • 正则表达式模式运算符只想匹配字符串,因此您必须将name(类型为Identifier)的解析树映射到如下字符串:"<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>;
}