Как задокументировать Rspe c let type - PullRequest
0 голосов
/ 16 июня 2020

Допустим, у меня есть следующий код

let(:document) { FactoryBot.create :document }
let(:mail) do
  # @type [User]
  celebrated_user = FactoryBot.create :user
  # @type [Rule]
  rule = FactoryBot.create :rule, document: document
  CelebrationMailer.birthday celebrated_user, document, rule
end

День рождения CelebrationMailer # задокументирован следующим образом

# @param [User] celebrated_user
# @param [Document] document
# @param [Rule] rule

В let(:mail) RubyMine (и, возможно, некоторые другие инструменты с типами) распознают документ переменная как объект типа.

RubyMine's tooltip about wrong type

Как я могу задокументировать let , чтобы инструменты распознавали document let / variable как тип документа ?

Пробовал @type, @return, @attr_reader.

1 Ответ

0 голосов
/ 16 июня 2020

Ну, а что делает let? Он создает метод, имя которого задается аргументом символа, а возвращаемое значение - возвращаемым значением блока.

Итак, если вы хотите написать тип для этого, вам придется

  • возьмите символ и превратите его в имя метода
  • возьмите тип возвращаемого значения блока и превратите его в тип возвращаемого значения метода

I Я почти уверен, что это невозможно с обозначениями типа RDo c или YARD.

Итак, лучшее, что вы можете сделать, это syntheti c attribute reader :

# @!attribute [r] document
#   @return [Document] a fake document
let(:document) { FactoryBot.create :document }

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

# Defines a memoized method
# @param [Symbol] name the method name
# @param block how to compute the value
# @!macro [attach] let
#   @!attribute [r] $1
#     @return the value defined by the block
def let(name, &block) end

Это сообщит YARD, что везде, где он видит вызов let, он должен вставить Syntheti c блок документации для считывателя атрибутов, имя которого является первым аргументом let.

Однако он не позволит вам использовать тип блока. Это единственные существующие переменные интерполяции:

  • $0 - имя вызываемого метода
  • $1, $2, $3,… - N-й аргумент в вызове метода
  • $& - полная строка исходного кода

Что будет работать, если let взял второй аргумент, который является типом , то вы могли бы написать макрос, подобный этому:

# Defines a memoized method
# @param [Symbol] name the method name
# @param [Module] type the type of the memoized value
# @param block how to compute the value
# @!macro [attach] let
#   @!attribute [r] $1
#     @return [${-1}] the value defined by the block
def let(name, type, &block) end

И тогда вы бы назвали его так:

let(:document, Document) { FactoryBot.create :document }

Но это не то, как разработан RSpe c, так что лучшее, что вы можете сделать, это считыватель атрибутов syntheti c из моего первого предложения.

...