Хороший способ изменить класс и сбросить его?- Отражение? - PullRequest
2 голосов
/ 07 сентября 2011

Я пытаюсь создать метод, который может изменить класс в файле и вывести его в тот же файл.

Как лучше всего это делать?

Я пытаюсь сделать следующее:

Скажите, что у меня есть класс:

Test.php:

namespace test;
class Test{

}

... и я хочу обработать этот класс, чтобы окончательный результат был

Test.php:

namespace test;
class Test implements /interfaces/Entity{

}

С *str_replace * это будет что-то вроде:

function parseImplementation($src, $class, $interface){
    return str_replace("$class", " $class implements $interface", $src);
}

Я пробовал Reflection API, но я не могу найти способ отредактировать сам класс и вывести его в исходный код.

* 1027Есть ли плавный способ сделать это?str_replace не является опцией, потому что класс Test может реализовывать другие вещи и вводиться с табуляцией / пробелами в качестве разделителей.

1 Ответ

1 голос
/ 07 сентября 2011

Что вам нужно, так это система преобразования программ от источника к источнику .Это инструмент, который анализирует код для структур данных компилятора (абстрактных синтаксических деревьев), которые не зависят от компоновки и т. Д., А затем позволяет писать операции «если вы видите, а затем заменять их этими», которые работают со структурами данных компилятора.(Да, вы можете попытаться сделать это с помощью взлома строк, и это может работать для примера, который у вас есть в руках, но взлом строк в целом не будет надежным по той же причине, по которой вы не можете использовать просто взлом строк для разбора реальногоисходный код).

Для этого вам нужно что-то, что может надежно анализировать PHP и применять исходные тексты к преобразованиям исходного кода.Для этого существует не так много инструментов.

Наш инструментарий реинжиниринга программного обеспечения DMS с его PHP Front End - это то, что может.

Ваше конкретное преобразование может быть выполнено с помощью DMS следующим образом:

    domain PHP~PHP5;  -- declare the programming language DMS will process

    rule add_interface_to_class(class_name:identifier, 
                                m: class_members): 
          class_declaration -> class_declaration =
    "class \i { \m } "
     ->  "class \i implements /interfaces/\entity\(\){ \m } ";

   rule add_another_interface_to_class(class_name:identifier,
                                       ifaces:interfaces,
                                       m: class_members): 
          class_declaration -> class_declaration =
    "class \i implements \ifaces { \m } " 
    -> "class \i implements \ifaces,/interfaces/\entity\(\){ \m } ";

У меня есть два правила: одно для обработки случая, когда в вашем классе есть выражение реализует, и одно для обработки случая.где предложение Implements уже существует.

Неясно, как «тест пространства имен» сыграл в вашем примере, но если бы это было важно, вам нужно было бы добавить условный тест к каждому правилу, чтобы проверить идентификаторя был в "правильном" пространстве имен.

...