Мы рады объявить о нашем новом выпуске Retyped и о том, что мы добавили поддержку более 1200 новых библиотек привязки. Это доводит общее количество библиотек привязки, которые могут использоваться в проектах Bridge.NET, до 3600+.
«Retyped теперь поддерживает использование более 3600 библиотек JavaScript в проектах C # в сочетании с Bridge.NET».
Факты о повторном вводе
- 1500+ коммитов в основной репозиторий исходного кода Retyped
- Ретипированное решение включает 14 проектов и 25000 LOC (VS Code Metrics)
- Более 2000 модульных тестов охватывают логику синтаксического анализа и перевода.
- Retyped читает NPM, ОпределенноTyped и исходные репозитории для сбора файлов декларации TypeScript для каждой библиотеки.
- Retyped содержит 25000 файлов d.ts, принадлежащих более 4000 библиотекам
- Для созданных решений C # требуется 100 ГБ дискового пространства.
- Полная перекомпиляция занимает 2 часа (4 потока на Core i7)
- 3600+ перепечатанных пакетов теперь доступны на NuGet
- Общее количество скачиваний всех Retyped пакетов теперь превышает 1,0 миллиона.
- Самые популярные пакеты - Retyped.jquery и Retyped.node.
Развитие Retyped очень увлекательно для нашей команды, и мы продолжаем постепенно улучшать Retyped каждый день.
Что нового в Retyped 1.5
Этот выпуск включает исправления и улучшения примерно для 100 проблем, а важные новые функции описаны ниже.
Поддержка NPM
С момента своего создания Retyped использовал только ОпределенноТипед в качестве единственного источника файлов объявлений. Retyped new правильно управляет сотнями пакетов, опубликованных только в NPM или в отдельных репозиториях GitHub.
Помимо чтения исходных файлов .d.ts, Retyped также отслеживает метаданные для каждой библиотеки, включая автора (авторов), номер версии и описание. См. Пример decimal.js.
Многие библиотеки больше не публикуют свои официальные файлы .d.ts в DefinentyTyped, поэтому, чтобы обеспечить включение только самых последних выпусков библиотек, Retyped найдет официальное расположение источника и будет читать оттуда.
Виртуальные члены
Все члены класса (кроме членов ObjectLiteral) теперь объявляются с модификатором virtual
, который обеспечивает более чистый метод переопределения. Просто сравните следующие примеры кода.
Старый синтаксис
Https://deck.net/70b444440f3bdd37ee238ea64c29f915
public class MyConsole : SpecialConsole { [Name("Print")] // <-- overrides the external base member public void Print(string msg) { Console.WriteLine(msg); } } [External] public class SpecialConsole { public extern void Print(string msg); }
Новый синтаксис
Https://deck.net/fb15de62219f27a9379f07c84d143214
public class MyConsole : SpecialConsole { public override void Print(string msg) { Console.WriteLine(msg); } } [External] public class SpecialConsole { public virtual extern void Print(string msg); }
Выражения в объявлениях Enum
Retyped теперь может генерировать правильный C # для библиотек, объявляющих элементы перечисления с использованием выражений.
enum Permission { Nobody = 0, Owner = 1, Officer = 2, Member = 4, Moderator = 8, AllMembers = Owner | Officer | Member | Moderator }
Типы делегатов и наследование
Есть два способа объявить тип делегата в TypeScript:
type ToStringDelegate1 = (n: number) => string; interface ToStringDelegate2 { (n: number): string; }
Ранее Retyped создавал объявление делегата для ToStringDelegate1
и объявление интерфейса для ToStringDelegate2
. Теперь оба типа будут испускаться одинаково:
public delegate string ToStringDelegate1(double n); public delegate string ToStringDelegate2(double n);
Объявление интерфейса не будет свернуто до простого типа делегата, если оно содержит дополнительные члены или если оно является производным от другого делегата.
В этом случае могут быть сгенерированы некоторые вспомогательные члены (если возможно): конструктор, принимающий аргумент типа делегата и набор неявных операторов - все это поможет с инициализацией и приведением типов.
Типы фиксированных конструкторов
Типы конструкторов напоминают типы функций с основным отличием, они предполагают использование ключевого слова new
.
Чтобы гарантировать это, Retyped генерирует класс, содержащий конструктор, позволяющий инициализировать тип конструктора с помощью LINQ Expression. Выражение указывает на конкретный конструктор некоторого типа. Еще один полезный член - метод Invoke
, который вызывает предоставленный конструктор и создает экземпляр типа.
TypeScript
class A { /* .. */ } let aCtorType: new () => A; aCtorType = A; let a = new aCtorType();
C#
Https://deck.net/5fbcef09355da563d9b754561179d657
public class Program { public static void Main() { ACtorFn aCtorType; aCtorType = new ACtorFn(() => new A()); var a = aCtorType.Invoke(); } }
Заявления по умолчанию для импорта / экспорта
Ранее Retyped имел некоторые пробелы в обработке заявлений по умолчанию для экспорта.
Теперь такие операторы полностью поддерживаются как в логике синтаксического анализа, так и в логике разрешения типов. Итак, учитывая следующий код TypeScript:
declare module "test" { namespace NS { class A { } } export default NS.A; }
... будет создан следующий C #:
[Retyped.Scope] [Bridge.GlobalMethods] [Retyped.ExportedAs("NS.A", IsExportDefault = true)] [Bridge.Module(Bridge.ModuleType.UMD, false, Name = "test")] public static class test { [Retyped.Scope] public static class NS { [Bridge.Name("default")] [Retyped.ExportedAs("test.NS.A")] public class A : Retyped.IObject { } } }
Внешние модули
Было несколько улучшений, посвященных модулям окружения. К ним относятся предотвращение конфликтов имен, расширение, разрешение типов и поддержка различных методов импорта и экспорта, включая псевдонимы. Например, в TypeScript одна сущность может быть импортирована с использованием нескольких разных стилей операторов.
import * as lib from ".." let a: lib.A; import { A } from ".." let a: A; import A from ".." let a: A; import { A as B } from ".." let a: B;
Все вышеперечисленное теперь работает как в обычных, так и в эмбиентных модулях.
Общие ограничения
Это самая важная и в то же время сложная для обсуждения тема. Мы пытались исправить проблемы, связанные с общими ограничениями, но они возвращались в виде все более сложных сценариев.
Мы пришли к выводу, что ограничения TypeScript просто не могут быть обработаны с помощью системы ограничений C #. Это заставило нас задуматься о реализации нашего собственного механизма ограничения типов. Мы предложили реализовать новый атрибут [Where]
, позволяющий применять гибкие правила ограничений. Например, ограничение типов Union или Псевдонимов типов.
В настоящее время ведется дополнительная работа над реализацией атрибута [Where]
, и мы будем признательны за ваш отзыв. Подробнее см. Мост Проблема № 3452.
Тестирование разрешения типа
Как упоминалось выше, у нас есть более 2000 модульных тестов, которые помогают нам проверить качество и согласованность сгенерированного кода C # для Retyped во всех более чем 3600 поддерживаемых библиотеках. Управление таким большим количеством проектов с помощью связанного набора модульных тестов - непростая задача, требующая высокого уровня автоматизации.
Эта тема заслуживает отдельного сообщения в блоге, но на данный момент у нас есть интеграционные тесты, охватывающие весь жизненный цикл Retyped, включая loading libs -> parsing -> emitting C# -> generating solutions -> resolving all dependencies -> full recompilation -> generating NuGet packages -> publishing to NuGet
.
Перепечатанные демо
Сайт Retyped Demos в настоящее время содержит 15 демонстрационных проектов, и в ближайшее время будут добавлены новые. Исходный код всех демонстраций доступен на GitHub.
Создание многих повторных демонстраций включало простой перенос исходного примера с JavaScript на C #. В большинстве случаев нам удавалось просто скопировать / вставить код JavaScript непосредственно в проект C #, а затем выполнить несколько тривиальных корректировок, таких как преобразование сигнатур функций JavaScript в объявления методов C #.
Благодаря соглашению об именах Retyped, большая часть использования JavaScript API не требует настроек, таких как изменение регистра с camelCase на PascalCase. Эта основная функция Retyped экономит огромное количество времени, снижает количество точек отказа и обеспечивает совместимость с исходной библиотекой.
Мы пытаемся создать демонстрационные проекты с исходным кодом C #, который точно соответствует первоначальному замыслу авторов, включая как функциональность, так и стиль синтаксиса.
При использовании Retyped и Bridge удивительно стираются границы между разными технологиями и языками.
Повторное управление версиями
Схема управления версиями пакетов Retyped вызвала несколько вопросов, поэтому давайте обрисуем некоторые из наших начальных требований и окончательный подход.
Требования:
- Повторно набранные пакеты можно рассматривать как привязки Bridge.NET, что делает их зависимыми от Bridge.Core, который предоставляет информацию о требуемой версии Bridge.
- Нам нужно было отслеживать, какая версия компилятора Retyped использовалась для создания пакета.
- Файлы деклараций тесно связаны с версией TypeScript, для которой они созданы. Это еще одна информация, которую необходимо идентифицировать.
- У каждой библиотеки есть своя собственная версия, поэтому она также должна быть отражена в пакете Retyped.
- Процесс сборки полностью автоматизирован, поэтому требовалось указать временную метку даты компиляции.
Подход:
- Базовый пакет был создан и добавлен как зависимость к каждому повторному пакету. Пакет назывался Retyped.Core, он содержит специфичные для Retyped типы, такие как атрибуты. Пакет Retyped.Core зависит от Bridge.Core - вместе они предоставляют информацию о версиях компилятора Retyped и Bridge.NET соответственно.
- Повторно типизированные пакеты, такие как Retyped.es5 или Retyped.dom, построены на основе базовых библиотек TypeScript, поэтому они могут представлять версию TypeScript.
- Пакет Retyped, созданный для библиотеки, получает версию этой библиотеки.
- Все упомянутые выше пакеты получают версию patch , представляющую количество дней, прошедших с 1 января 2000 года (калькулятор).
В качестве примера возьмем пакет Retyped.node и некоторые его зависимости:
- Retyped.node 9.6.6685 = NodeJS 9.6
- Retyped.dom 2.8.6685 = TypeScript 2.8
- Retyped.Core 1.5.6685 = Retyped 1.5
- Bridge.Core 17.0.0 = Bridge 17.0
- * .6685 = дата выпуска была 6685 дней после 2000–01–01 = 2018–04–20
Надеюсь, что эта информация поможет вам лучше ориентироваться между версиями и выпусками пакетов Retyped.
Повторно напечатанная дорожная карта
Этот выпуск является важной вехой для Retyped. Прошло много времени с тех пор, как мы запустили такое массовое обновление, синхронизирующее с последними объявлениями.
Впрочем, впереди еще дорога. Имеются планы по реализации таких функций, как ночные инкрементные сборки и автономные пакеты со всеми необходимыми файлами JavaScript для каждого встроенного пакета.
Ретипованный и мост Премиум
Знаете ли вы, что Bridge.NET - это бесплатное программное обеспечение с открытым исходным кодом, поддерживаемое сообществом? Мы финансируем разработку Bridge и Retyped, предоставляя дополнительные плагины Premium и ускоренную службу поддержки Premium. Пожалуйста, ознакомьтесь с опциями Bridge Pro и Enterprise Premium.
Спасибо за интерес к Retyped и Bridge.NET!