UniSharping – это конвертер кода C# на другие языки программирования: Java, Python, PHP, JavaScript и др. Основная «фишка» и отличительная особенность от других конвертеров состоит в том, что результирующий код получается работоспособным без какой-либо его ручной правки. Но приходится немного подправить исходный код C#. То есть мы ориентируемся не на задачу разовой миграции, а на продолжение разработки на C# с получением в любой момент рабочего кода на нужном языке.
Эта амбициозная задача может быть в принципе решена, если исходный код будет удовлетворять некоторым ограничениям, касающимся конструкций языка, системных библиотек и технологий. Данное ограниченное подмножество условно здесь назвали U# (Universal Sharp).
В целях кроссплатформенности Компания Microsoft уже сделала ограничение .NET Framework в плане библиотек и технологий: .NET Core. Это как бы первый шаг в нужном направлении, U# делает второй шаг к «кросспрограммируемости».
- UniSharping.zip - исполняемые модули (студия и консоль) с настроечными файлами, работают под .NET Framework 4.0 и выше;
- Test.zip - проект с юниттестами для Visual Studio 2017;
- UniSharping.Overview.docx - краткое описание и основные принципы работы;
- UniSharping.Correct.docx - ограничения и способы их преодоления;
- UniSharping.Extension.docx - настройка на новые системные классы и методы;
Есть сайт с online-демонстрацией, список поддержанных классов можно посмотреть здесь.
Ограничений U# в конструкциях языка оказалось немного – это атавизмы goto
, а также yield
(для Java), не моделируемый адекватно в автоматическом режиме. Игнорируются атрибуты [...] у методов классов. Не рекомендуется (хотя и можно) использовать struct, есть нюансы с наименованиями – всё это подробно описывается в отдельном документе. Парсер U# выдаёт ошибки и предупреждения, и для гарантии корректной генерации следует так подкорректировать исходный код C#, чтобы они в идеале совсем исчезли. Если всё-таки нужно сохранить исходный вариант, то можно использовать директивы препроцессора #if JAVA || PHP … #else … #endif. Данные ограничения действуют на уровне движка U# и не подлежат коррекции извне, как и список поддерживаемых языков.
А вот ограничения на уровне системных библиотек заданы не жёстко и конфигурируются извне через специальные текстовые файлы, определяющие, как переводить на соответствующий язык тот или иной класс и его члены. Если есть прямой аналог, то он и указывается, если ситуация сложнее, то пишется или фрагмент кода конечного языка, или вообще специальный (сервисный) класс, решающий нужную задачу. В совсем уж сложных случаях приходится «хардкодить» на уровне движка, но такие ситуации довольно редки (с десяток). Порядок настройки на системные классы и их члены описываются в отдельном документе (UniSharping.Extension.docx).
Что касается технологий , то здесь список ограничен на уровне движка консольным приложением и юнит-тестами (UnitTest) . Ну и отдельные Lib-проекты, как частный случай, переводятся в соответствующие конструкции нужного языка.
Вообще для успешного перевода исходный проект C# (solution) должен иметь некоторую запускаемую часть, проверяющую работоспособность в рамках исходного C#. Хорошо, если это обширная система авто-тестов (стандартных UnitTest в разных реализациях или самописных), но по минимуму должно быть хотя бы консольное приложение, которое при запуске без какого-либо пользовательского вмешательства отрабатывает правильно. Необходимость этого очевидна – после генерации на конечный язык можно сразу проверить работоспособность. В идеале все тесты должны работать аналогично C#.
- Автотесты Tests.zip
- Проект Pullenti с его набором из около 1500 автотестов
- Ряд внутренних коммерческих проектов
- На самом движке - перевод самого себя (консольной части) с C# на другой язык
- расширять список поддерживаемых системных методов и классов, возможно, не без Вашего участия. Дело в том, что свои проекты я уже перевёл, и все используемые мной системные методы "исчерпаны". Нужны новые живые проекты.
- дописать автотесты для всех конструкций языка и поддерживаемых системных методов.
- подтянуть Python, PHP, JavaScript до уровня Java. Сейчас они поддержаны на уровне моего базового проекта Pullenti, однако Java по сравнению с ними ушёл далеко вперёд на других проектах.
- поддержать Scala хотя бы на уровне проекта Pullenti.
- поддержать С++. Да, осознаю, это очень сложно, так как неясно при освобождении памяти - какой указатель является ссылкой, а для какого нужно делать delete. Но есть идеи...