2017-09-13 3 views
1

Ich versuche, einen Java-Methodennamen mit einer Regex zu vergleichen, aber ich bin nicht sicher, wie man es in Rascal macht. Ich möchte eine Methode abgleichen, deren Name mit test beginnt (z. B. JUnit 3-Testfälle), und sie in einen JUnit 4-Testfall mit der @Test Annotation umwandeln und das test Präfix entfernen. Mein Code sieht wie folgt aus:Übereinstimmender deklarierter Methodenname zu Regex

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

Dieser Code führt zu dem folgenden Fehler:

Expected str, but got Identifier 

Gibt es eine Möglichkeit, die name Methodenbezeichner als String zuzugreifen, so kann ich versuchen, es zu entsprechen? Wenn nicht, was ist der beste Weg, um diese Aufgabe zu erfüllen?

Antwort

1
  • Der RegexMuster Operator will gegen Strings nur passen, so dass Sie den Parsing-Baum von name zur Karte haben (die vom Typ Identifier ist) in einen String wie folgt: "<name>".
  • Um die neue Namenszeichenfolge wieder in den Speicherort eines Bezeichners zu splicen, müssen Sie sie ähnlich wie: [Identifier] newName wieder zuordnen.

Das Endergebnis sieht wie folgt aus:

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

Sie können mit einer benannten Gruppe auch direkt den Schwanz passen heraus:

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

Es funktionierte großartig! Vielen Dank! – urielSilva

Verwandte Themen