[Nitra] Новости от 28.06.2017
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.06.17 23:53
Оценка: 44 (5)

BindResult[TSymbol]


Провел масштабную модернизацию механизма связывания (binding-а).

Зачем это нужно и что это дает?

В Nitra биндинг встроен в библиотеки. Код биндинга зашит в библиотечный ast Reference.

Это дает некоторую автоматику и обобщенный принцип. Но это несло в себе существенный недостаток. Дело в том, что связывание всегда производится с базовым типом символа DeclarationSymbol. Это значит, что связывании проводится с первым попавшимся символом. В дальнейшем, во время резолва, можно уточнить тип символа, но если в области видимости был символ неподходящего типа, то мы получали ошибку, так как информация о затененных (этим символом) других символов терялась.

Я долго думал что сделать, чтобы можно было производить связывание (или уточнение связывания) с затененными сиволами. В итоге остановился на следующем решении.

Теперь связывание проходит не с конкретным символом или их списком (в случае неоднозначности), а со специальным типом способным хранить иерархию символов. Это вариантный тип BindResult[TSymbol]. Он может хранить следующие варианты (и их комбинации):
| Single
| Multiple
| Hiding
| Union
| Nil

Можно сказать, что этот тип повторяет иерархию областей видимости (Scope-в), но без излишних деталей и вложенности.

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

Для этого типа доступны методы:
public Filter[TConcreteSymbol]() : BindResult[TConcreteSymbol]
  where TConcreteSymbol : DeclarationSymbol

/// Filter by predicate. Filter by TConcreteSymbol If predicate is null.
public Filter[TConcreteSymbol](predicate : Predicate[TConcreteSymbol]) : BindResult[TConcreteSymbol]
  where TConcreteSymbol : DeclarationSymbol

public Map[TConcreteSymbol](algorithm : ResolutionAlgorithm[TSymbol, TConcreteSymbol]) : BindResult[TConcreteSymbol]
  where TConcreteSymbol : DeclarationSymbol


Которые позволяют фильтровать BindResult[TSymbol] по типу и значению символов и отображать BindResult[X] на BindResult[Y].

Связывание более 1 символа не является автоматически ошибкой, так как в процессе резолва лишние символы могут быть отброшены.

То что BindResult хранит иерархию сокрытия позволяет процедуре резолва пройти по иерархии вниз отбросив скрывающие символы и взять скрытые. Так если произошло связывание с локальной переменной, но процедура резолва хочет произвести связывание с одноименным типом, она может отфильтровать BindResult по типу и отбросить, таким образом, локальные переменные и поля.

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

Ref[TSymbol]


Претерпел изменения и Ref[TSymbol] используемый в Nitra при резолве. Ref[TSymbol] перестал быть вариантным, так как за хранение информации о неоднозначности и неудаче резолва или связывания переехала в BindResult.

В задачи Ref теперь входит кэширование значения символов, описание взаимосвязей резовлва (по средствам свойства ResolvedTo) и информировании пользователя о неудаче связывания.

У Ref[TSymbol] есть ряд наследников оптимизирующих хранение и кэширование данных.

Ну, и Ref[TSymbol] по-прежнему реализуют псевдо-зависимые свойства позволяющие использовать их в коде вычисления зависимых свойств.

ast Reference и Scope


Немного изменился интерфейс ast-а Reference и типа Scope. Их методы Bind, как бы, вывернуты наизнанку.

Теперь методы Bind у Scope возвращают BindResult[TSymbol], а метод Reference.Bind принимает в качестве параметра Scope и возвращает Ref[TSymbol].
  public partial class Reference : AstBase
  {
    public Bind[TSymbol](scope : Scope) : Ref[TSymbol]
      where TSymbol : DeclarationSymbol
    ...
  }

  public abstract class Scope : ISerializable
  {
    public abstract Bind[TSymbol](reference : Reference)        : BindResult[TSymbol] where TSymbol : DeclarationSymbol;
    public abstract Bind[TSymbol](isMatch : Predicate[TSymbol]) : BindResult[TSymbol] where TSymbol : DeclarationSymbol;
    ...
  }


Кроме того был убран метод Scope.BindMany. Зато появился метод Bind принимающий предикат. Так же бы удален метод автодополнение при вводе. Теперь его роль будет играть метод Bind принимающий предикат.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Отредактировано 29.06.2017 12:55 VladD2 . Предыдущая версия . Еще …
Отредактировано 29.06.2017 12:54 VladD2 . Предыдущая версия .
Отредактировано 29.06.2017 12:53 VladD2 . Предыдущая версия .
Отредактировано 28.06.2017 11:53 VladD2 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.