Хабрахабр

UniSharping: конвертирование кода C# в Java и Python

Рекомендуется, например, для технической документации. С 70-х годов развивается Simplified English, цель которого — определение подмножества языка, понятного широкому кругу неносителей языка. Причём конвертации не однократной (миграция), а постоянной для расширения интеграционных возможностей проекта на C# — чтобы в любой момент можно было получить рабочий код на другом языке без необходимости какой-либо его правки. Автоматические переводчики на таком подмножестве будут работать заведомо корректнее, в идеале генерируя текст, не требующий ручной корректуры.
Если применить этот подход к C# для задачи автоматической конвертации кода в другие языки программирования, то можно выделить подмножество конструкций языка, системных библиотек и технологий, которые потенциально могут транслироваться в широкий круг других языков.

NET для решения этой задачи мы назвали U# (Universal Sharp), а процесс конвертации и его инструмент — UniSharping. Ограничение C#. Исполняемые модули, настройки и документация выложены на GitHub, система бесплатна для некоммерческого использования (Non-Commercial Freeware).

NET Framework в плане библиотек и технологий: . В целях кроссплатформенности Компания Microsoft уже сделала ограничение . Это как бы первый шаг в нужном направлении, U# делает второй шаг к «кросспрограммируемости». NET Core.

Не рекомендуется (хотя и можно) использовать struct, есть нюансы с наименованиями – всё это подробно описывается в отдельном документе. Ограничений U# в конструкциях языка оказалось немного – это атавизмы goto и case goto, а также yield, не моделируемый адекватно в автоматическом режиме. Если всё-таки нужно сохранить исходный вариант, то можно использовать директивы препроцессора #if JAVA || PHP … #else … #endif. Парсер U# выдаёт ошибки и предупреждения, и для гарантии корректной генерации следует так подкорректировать исходный код C#, чтобы они в идеале совсем исчезли. Данные ограничения действуют на уровне движка U# и не подлежат коррекции извне, как и список поддерживаемых языков.

Если есть прямой аналог, то он и указывается, если ситуация сложнее, то пишется или фрагмент кода конечного языка, или вообще специальный (сервисный) класс, решающий нужную задачу. А вот ограничения на уровне системных библиотек заданы не жёстко и конфигурируются извне через специальные текстовые файлы, определяющие, как переводить на соответствующий язык тот или иной класс и его члены. Порядок настройки на системные классы и их члены описываются в отдельном документе. В совсем уж сложных случаях приходится «хардкодить» на уровне движка, но такие ситуации довольно редки (с десяток). Вот список поддержанных классов C# и их членов с аналогами на Java и Python в текущей версии на сайте, там же есть online-демо.

Ну и отдельные Lib-проекты, как частный случай, переводятся в соответствующие конструкции нужного языка. Что касается технологий, то сейчас список ограничен консольным приложением и юнит-тестами (UnitTest).

Хорошо, если это обширная система авто-тестов (стандартных UnitTest в разных реализациях или самописных), но по минимуму должно быть хотя бы консольное приложение, которое при запуске без какого-либо пользовательского вмешательства отрабатывает правильно. Для успешного перевода исходный проект C# (solution) должен иметь некоторую запускаемую часть, проверяющую работоспособность в рамках исходного C#. В идеале все тесты должны работать аналогично C#. Необходимость этого очевидна – после генерации на конечный язык можно сразу проверить работоспособность.

Мой основной проект SDK Pullenti по обработке естественного языка — идеальный кандидат для конвертации: большой объём сложного и постоянно совершенствуемого кода. Идея такого конвертера витала давно. Он переводил проект Pullenti на Java, а также сам себя на Java.
Следующие полгода конвертер развивался на нескольких внутренних проектах, которые были в компании, в основном посредством расширения системных классов.
Весной 2018 появилась мысль поддержать и Python, что и было реализовано к лету. Для интеграции с Java приходилось оборачивать в web-сервисы, tcp-сервера и пр.
Летом прошлого года нашлось время и силы для создания первого варианта. Пришлось летом полностью переделать движок для потенциальной возможности нескольких конечных языков. Но включение второго языка не было предусмотрено в начальной версии и получилось коряво. Надеюсь, это множество будет расширяться не без вашей помощи. Также настройки на системные классы из хардкода были вынесены во внешние текстовые файлы.

Дальнейшие планы пока таковы:

  • подтянуть Python до уровня Java. Сейчас Python поддержан на уровне Pullenti, однако Java по сравнению с ним ушёл далеко вперёд на других проектах.
  • поддержать PHP хотя бы на уровне проекта Pullenti.
  • поддержать С++. Да, осознаю, это очень сложно, так как неясно при освобождении памяти — какой указатель является ссылкой, а для какого нужно делать delete. Но есть идеи...

Благодаря конвертеру UniSharping их SDK может стать ещё и "кросспрограммным", что расширит круг потенциальных пользователей.
В последнее время в России усилились позиции СПО, которые стали обязательными в большинстве государственных структур и некоторых крупных компаниях. В основном тем, кто разрабатывает потенциально кроссплатформенные SDK на C#. NET Core тоже СПО не всегда получится, потому что "Microsoft". Объяснить, что . Чтобы внедрить продукт в "СПО-компанию", можно выделить логическую часть проекта (back-end), её автоматически конвертировать в релизы по мере необходимости, а визуальную часть (front-end) делать на СПО. Пусть некоторая компания разрабатывает свою информационную систему на C#. То есть продолжать разработку на C#, а на Java только front-end.

Если кто видит такую возможность, то её вполне можно реализовать в UniSharping. Я не исключаю, что в принципе возможна конвертация и web-проектов (с ограничениями, естественно), но у меня нет для этого нужных навыков и информации.

Также настройка ещё неподдержанных системных классов и методов и исправление ошибок самого UniSharping (с моей помощью) — работа ещё та. Отмечу, для для реального сложного проекта C# поддержка Java или другого языка потребует некоторых усилий по модификации кода, выделении в проекте портируемой части, "обкладывание" её юнит-тестами. Но процесс сходящийся, в конце которого проект ожидает бонус "кросс-программности".

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть