Как было сказано ранее, код Visual Studio — это фреймворк с открытым исходным кодом, поддерживаемый Microsoft, вы можете найти код на Github:

git clone https://github.com/Microsoft/vscode.git

Репозиторий также предоставляет классное руководство, чтобы настроить среду разработки на вашем компьютере и начать вносить свой вклад в проект. Кстати, если вы посмотрите на теги репозитория, то увидите, что за кодом Visual Studio стоят две основные технологии: Typescript и Electron.

Машинопись

TypeScript — это типизированный надмножество JavaScript, который компилируется в обычный JavaScript. О машинописном тексте я уже говорил в статьях: Введение в машинописный текст, Введение в машинописный текст: возможности языка, Принципы SOLID с использованием машинописного текста, Инверсия управления и внедрение зависимостей в машинописном тексте.

Typescript очень полезен применительно к большим и распределенным кодовым базам, код Visual Studio основывает на нем весь свой код.

Электрон

По сути, Electron может запускать ваши приложения HTML, JS, CSS как клиентские приложения. Он создает кроссплатформенные настольные приложения и работает как мост между входными и выходными данными ОС и вашим приложением и обеспечивает единый уровень.

Структура проекта

Код Visual Studio был создан для расширяемости. Многие функции, например языки, обычно поддерживаются и угрожают в виде расширений. Однако исходный код также реализует часть core, которая содержит все основные API-интерфейсы редактора.

core разделен на следующие слои:

  • base: предоставляет общие утилиты, используемые в других слоях;
  • platform: определяет поддержку внедрения служб и общие службы для кода Visual Studio;
  • editor: оборачивает редактор кода Visual Studio code, который называется «Монако»;
  • languages: как было сказано ранее, по историческим причинам не все языки реализованы в виде расширений (пока);
  • workbench: размещает редактор «Монако» и предоставляет некоторые основные компоненты, такие как: проводник, строка состояния или строка меню;

Базовый слой

Предоставляет общие утилиты и стандартный блок пользовательского интерфейса. Слой base разделен на несколько подслоев: browser, common, node, parts, test, worker;

Весь исходный код внутри этого слоя предназначен для того, чтобы помочь процессу разработки, давайте сосредоточимся на некотором коде внутри этого слоя, например, на файле collections.ts:

Как видите, он предоставляет некоторые абстрактные интерфейсы, которые действуют как словари, и методы расширения, такие как: forEach<T>, groupBy<T>, которые запрашивают коллекции. Все компоненты внутри этого уровня используются во всех службах, и именно поэтому они спроектированы так, чтобы быть максимально абстрактными.

Слой редактора

Он содержит определение редактора кода, который называется Монако. Редактор Monaco генерируется прямо из исходников кода Visual Studio с некоторыми прокладками вокруг служб, необходимых коду для запуска в веб-браузере за пределами своего дома.

Это еще один проект Microsoft с открытым исходным кодом, вы можете клонировать репозиторий отсюда:

git clone https://github.com/Microsoft/monaco-editor.git

Слой верстака

Уровень рабочей среды содержит Монако и интегрирует все компоненты редактора в код Visual Studio. Давайте быстро взглянем на интерфейс IHistoryService:

Он предоставляет методы для навигации по истории файлов. Интерфейс также объявлен как декоратор на line 11:
export const IHistoryService = createDecorator<IHistoryService>('historyService');

Таким образом, его можно использовать как зависимость в внедрении конструктора. Подробнее о системе внедрения зависимостей кода Visual Studio мы поговорим в следующем подразделе.

Обещания

API кода Visual Studio представляет собой асинхронные операции с обещаниями. Обработка промисов не зависит от конкретной библиотеки промисов. Обещания выражаются в API типом Thenable. Thenable представляет собой общий знаменатель метода тогда.

Вот определение интерфейса Thenable:

Thenable просто оборачивает любой тип в промис, а затем предоставляет метод для обработки промиса. Когда использование обещания необязательно, API указывает на это, возвращая or-типы:
provideNumber(): any | Thenable<any>

Одноразовый шаблон

API кода Visual Studio использует шаблон удаления, чтобы избежать ненужной траты ресурсов. Шаблон удаления в основном используется в языках, среда выполнения которых имеет автоматическую сборку мусора. Хотя Typescript не реализует одноразовый шаблон как стандартную функцию, см. issues/16459, код Visual Studio реализует эту функцию на уровне типа определения, чтобы представить тип который может освобождать ресурсы, такие как события и таймеры:

На основе сервисов внедрения зависимостей

Код организован вокруг служб, большинство из которых определены на уровне platform. Сервисы попадают к своим клиентам через внедрение конструктора.

Как было предложено для ES7, объявление зависимости службы происходит путем добавления соответствующего украшения к аргументу конструктора:

Услуга определяется двумя частями:

  • интерфейс службы
  • идентификатор услуги;

Давайте посмотрим на конкретный пример определения сервиса, взятого из слоя platform:

Как видите, предыдущий код определяет интерфейс, который описывает файл IClipboardService. Он также создает декоратор, который будет использоваться в качестве параметра внедрения конструктора. С другой стороны, интерфейс должен быть реализован конкретным классом:

Наконец, услугу можно использовать следующим образом:

Рабочий процесс внедрения зависимостей

Код Visual Studio не зависит от каких-либо сторонних плагинов для внедрения зависимостей. Почти вся логика находится внутри слоя platform.

Давайте углубимся в реализацию инстанцирования службы. Мы можем найти такую ​​логику внутри файла instantiation.ts:

Внутри файла instantiation.ts есть 3 ключевых объекта:

  • ServiceIdentifier<T>: описать экземпляр универсальной службы;
  • createDecorator<T>(serviceId:string): предоставляет уникальную точку входа для инициализации новых служб;
  • storeServiceDependency: предоставляет способ хранения экземпляров служб;

Функция createDecorator<T> принимает serviceId в качестве уникального аргумента: если служба присутствует и уже инициализирована, она возвращает службу; С другой стороны, если служба отсутствует, она создает новый экземпляр и сохраняет его в коллекции инициализированных служб с помощью файла storeServiceDependency.

Заключительная мысль

В заключение, цель статьи — погрузиться в код Visual Studio. Проекты с открытым исходным кодом — это отличная возможность понять, что стоит за крупномасштабными приложениями, а их анализ — отличная отправная точка для того, чтобы начать вносить свой вклад и стать частью сообщества открытого исходного кода.

Вот несколько ссылок на эту тему:



https://github.com/samueleresca/decoration-ioc (Сделано joelday)



Фото на обложке: SEATTLE PUBLIC MARKET BY CARL FUNSETH

Ваше здоровье :)