Skip to content

Latest commit

 

History

History
264 lines (165 loc) · 21.5 KB

LanguageSupport.md

File metadata and controls

264 lines (165 loc) · 21.5 KB

Language Support in IDEs

Этот документ описывает необходимую функциональность для поддержки языка в таких редакторах как JetBrains IDEs, VS Code и другие. Основная цель, единообразие возможностей в разных редакторах и отслеживание прогресса.

В дальнейшем, каждая реализованная часть будет помечаться эмодзи JB или VS Code для указания, что функциональность была реализована.

Base implementation

VS Code и другие редакторы используют протокол LSP который определяет общение между Language Server и редактором.

JB IDEs используют собственный API для поддержки языка в рамках IDE, пусть они добавили первичную поддержку LSP, этот API все еще очень сильно уступает встроенному в IDE.

Features

Completion

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

Structure completion

Структурное автодополнение включает в себя автодополнение ключевых слов, конструкций типа if/else или создание пустых структур, контрактов и прочего. Такое автодополнение не требует дополнительной информации из других файлов. Такое автодополнение может быть реализована в обоих API.

Поддержка в IDE: JetBrains ✅, VS Code ✅

Следующий список показывает все необходимые конструкции, для которых мы хотим видеть такое автодополнение:

  • contract Name {}
  • struct Name {}
  • message Name {}
  • trait Name {}
  • const Name: Type = value
  • if (cond) {}
  • else {}/else-if (cond) {}
  • while (cond) {}
  • do {} unril (cond);
  • foreach (key, value in map) {}
  • fun name() {} включая все возможные варианты (extends, native)
Postfix completion

Поддержка в IDE: JetBrains ✅, VS Code ❓

Постфиксное автодополнение это частный случай структурного автодополнения. Это автодополнение срабатывает когда пользователь написал некоторый постфикс (например, for) и нажал автодополнение, в этом случае такое автодополнение разворачивает слово в целую конструкцию (в примере, в foreach).

mapping.for<caret>

Конвертируется в:

foreach (key, value in mapping) {}

Следующий список показывает все необходимые конструкции, для которых мы хотим видеть такое автодополнение:

  • <expr>.for для foreach (key, value in expr) {}
  • <expr>.let для let name = expr;
  • <expr>.dump для dump(expr);

Logical completion

Поддержка в IDE: JetBrains ✅, VS Code ✅

Логическое автодополнение работает как автодополнение, которое учитывает логику языка (например, определения переменных или функций) и использует вывод типов для своей работы (автодополнение полей или методов после точки).

fun bar(): Int { return 0; }

fun foo(param: Cell) {
	let a = bar();
	if (a == 10) {
		<caret>
	}
}

Например, в примере выше, логическое автодополнение должно предложить переменную a, параметр param и функции bar и foo.

Следующий список показывает ключевые слова которые должны автодополняться с учетом логики:

  • return - Автодополнение return должно учитывать возвращаемый тип функции.
    • Если функция не возвращает ничего, при автодополнении должна вставляться автоматическая точка с запятой, а каретка перемещена на место после точки с запятой.
    • Если функция возвращает числа, строки или boolean, то в списке автодополнения должны быть варианты с проставленным дефолтным значением.
    • Если функция возвращает Option, то в списке автодополнения должен быть вариант с return null;
    • Если функция возвращает что-либо, при автодополнении каретка должны быть после return через пробел, за которой должна идти точка с запятой return <cursor>;

Следующий список показывает какие определения должны быть в автодополнении в рамках функции:

  • Локальные переменные определенные до места в функции, где расположена каретка

  • Параметры функции в которой находится каретка

  • Top-level определения из файла и импортированных модулей (включая stdlib)

    • При автодополнении функции:
      • если функция не принимает аргументов, курсор должен ставиться после скобок foo()<caret>
      • если функция принимает один аргумент self и вызывается как метод, курсор должен ставиться после скобок a.foo()<caret>
      • в остальных случаях, когда у функции есть аргументы, каретка должна помещаться внутри скобок: foo(<caret>)
      • если функция ничего не возвращает и это контекст statement, то автоматически добавлять точку с запятой и перемещать курсор после нее
    • При автодополнении структур:
      • необходимо вставить имя и фигурные скобки, поместив курсор между ними: Foo {<caret>}
      • после автодополнения автоматически вызывать автодополнение (JetBrains ✅, VS Code ❓) для автодополнения полей
      • если каретка находится на месте, где ожидается тип, не вставлять фигурные скобки
  • Методы трейта или контракта в которых находится каретка

    • при автодополнении необходимо автоматически вставить self. префикс, чтобы код корректно вызывал этот метод
    • вставка скобок и перемещение каретки используют те же правила что и для функций
  • Если каретка находится внутри Foo { <caret> } и Foo это структура или сообщение, то предлагать быстрое действие (JetBrains ✅, VS Code ❓) которое автоматически заполнит все поля дефолтными значениями с их редактированием через tab.

  • Если каретка находится внутри Foo { <caret> } и Foo это структура или сообщение, предлагать автодополнение для полей этой структуры/сообщения. Если поле уже было ранее заполнено, оно не должно появляться в списке. Учитывать, что поля могут быть заполнены без указания ключа (Foo { 10, 20, <caret> }).

  • При автодополнении, если каретка находится в рамках ExpressionStatement автоматически добавлять ; и переводить каретку на место перед ;, так как пользователь может хотеть ввести chain вызовов.

    <caret>
    // after completion
    foo()<caret>;
    

    Для случаев, когда мы находимся в рамках выражения (например, в аргументах функции), точка с запятой не должна добавляться!

  • Если функция расположена внутри трейта или контракта, давать автодополнение для self.

  • Если функция расположена внутри трейта или контракта, при вводе имени метода или поля трейта/контракта, при автодополнении добавлять автоматически self. перед именем.

Следующий список показывает какие определения должны быть в автодополнении типа:

  • Top-level определения из файла и импортированных модулей (включая stdlib) включая структуры, сообщения, трейты и примитивы
  • Если каретка находится после as, список должен включать все возможные типы. Что делать если это не Int?
  • При автодополнении типа поля, если вводится Int то предлагать все возможные варианты типа после as.

Следующий список показывает автодополнения которые должны быть доступны в рамках трейта или контракта:

  • Если трейт и контракт наследуются от трейтов, то при вводе слова override предлашать возможные варианты.
  • Если трейт и контракт наследуются от трейтов, то в списке автодополнения должны быть поля которые еще не были определены.
  • Автодополнение шаблона для receiver методов и для обычных методов.

Dot completion

Dot автодополнение вызывается, когда пользователь вводит точку (foo.<caret>). Такое автодополнение используется для полей и методов.

Documentation on hover

Поддержка в IDE: JetBrains ✅, VS Code ✅

Документация при наведении позволяет быстро узнать сигнатуры и описание символа.

В дополнение к отображению документации для символов, мы также можем показывать документацию для каждого ключевого слова с ссылкой на документацию. Это может быть полезно для новчиков который только изучают язык.

Parameter info

Поддержка в IDE: JetBrains ✅, VS Code ✅

Parameter info описывает параметр который в данный момент вводится в вызове функции. Эта информация позволяет быстро сориентироваться в параметрах функции.

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

Inlay hints

Поддержка в IDE: JetBrains ✅, VS Code ✅

Inlay hints позволяет добавить в редактор дополнительную информацию в виде не редактируемых inline блоков с текстом.

Следующие inlay hints должны быть добавлены:

  • Описание типа переменной
    • Если тип переменной тривиально выводим, то хинт не добавляется. Тип считает тривиально выводимым в следующих случаях:
      • присвоение создания структуры Foo{}
      • присвоение true или false
    • Если тип не удалось вывести, то хинт не показывается
  • Описание типа переменной в foreach
  • Имена параметров в вызове функции
    • Учитывать что self не нужно показывать если это вызов метода
  • Имена полей которые инициализируются при создании структуры
    • Только если имя не указано явно

Все хинты должны быть отключаемы через конфигурацию.

Go to references

Поддержка в IDE: JetBrains ✅, VS Code ✅

Поиск использований определения важная часть поддержки языка, так как позволяет быстро навигироваться между использованиями. Поиск должен работать как для глобальных определений (функции, структуры, тд), так и локальных (переменные, параметры).

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

Функция должна работать при использовании как на определении, так и при использовании на месте использования.

Go to implementations

Поддержка в IDE: JetBrains ✅, VS Code ✅

Переход к имплементациям позволяет быстро найти всех, кто наследуется от определенного трейта. Данная функциональность позволяет также должна искать все реализации абстрактных методов трейтов, а также реализации всех полей трейта.

Highlight references

Поддержка в IDE: JetBrains ✅, VS Code ✅

Подсветка использований прямо в коде когда курсор находится на определении, преследует те же цели что и "Go to references", только отображает все локально. Также, плагины должны уметь различать когда переменные/параметры используются, а когда перезаписываются и подсвечивать их разными цветами (JetBrains ✅, VS Code ✅).

Функция должна работать при использовании как на определении, так и при использовании на месте использования.

Rename refactoring

Поддержка в IDE: JetBrains ✅, VS Code ✅

Переименование определения удобная возможность которая позволяет эффективно и надежно переименовывать элементы. Переименование должно работать как для глобальных определений (функции, структуры, тд), так и локальных (переменные, параметры).

Переименовывание не идентификатора должно быть запрещено. Переименование элементов из стандартной библиотеки должно быть запрещено.

Функция должна работать при использовании как на определении, так и при использовании на месте использования.

Если новое имя символа конфликтует с другим символом, то переименование должно быть остановлено и выдана ошибка с описанием причины.

При переименовании поля трейта, если у этого трейта есть наследники, нужно решить нужно ли переименовывать и поля в наследниках. Также нужно понять что делать при переименовании в наследники, нужно ли переименовывать в родителе (при возможности).

Foldings

Поддержка в IDE: JetBrains ✅, VS Code ✅

Foldings позволяют пользователю сворачивать различные блоки кода для упрощения чтения.

Следующие узлы должны уметь сворачиваться:

  • Структуры, сообщения, трейты, контракты, функции и импорты с более чем одной записью
  • Многострочные комментарии и однострочные комментарии с несколькими строками
  • if/else, while, until, foreach, Foo {} на нескольких строчках

Semantic highlighting

Поддержка в IDE: JetBrains ✅, VS Code ✅

Обычная подсветка с использованием TextMate грамматик позволяет добиться отличных результатов, чтобы улучшить их движок может предоставлять дополнительную подсветку на основе AST и на основе данных которые используются для разрешения имен.

Как минимум следующие конструкции должны иметь такую подсветку:

  • Переменные и параметры, так как их невозможно различить друг от друга
  • Обращение к полям и их инициализация

Code lens

Поддержка в IDE: JetBrains ✅, VS Code ✅

Code lens позволяют отображать над строкой или в ее конце кликабельную информацию, например, количество использований данного типа или автора по истории git.

Следующие code lens должны быть реализованы:

  • Показ автора по git истории (JetBrains ✅, VS Code ❓)
  • Показ количества использований (JetBrains ✅, VS Code ❓)
  • Go to parent field (JetBrains ✅, VS Code ✅)
  • Go to overidden method (JetBrains ✅, VS Code ✅)
  • Go to overrides (JetBrains ✅, VS Code ✅)
  • Go to inheritors (JetBrains ✅, VS Code ✅)

Document symbols

Поддержка в IDE: JetBrains ✅, VS Code ✅

Document symbols позволяют быстро прссмотреть символы определенные в текущем файле. В случае структур и сообщений, поля должны быть вложены в структуру. В случае трейтов и контрактов, поля, константы и методы также должны быть вложены в tree view в редакторе.

Workspace symbols

Поддержка в IDE: JetBrains ✅, VS Code ✅

Workspace symbols позволяют быстро искать символы по всему проекту. Бекенд должен уметь отдавать все top level определения.