Вам нужно написать абстрактный интерпретатор , который выполняет код со значениями типа. Таким образом, вы переходите к своему абстрактному интерпретатору через AST и записываете для каждой переменной отправленные сообщения или известные типы. И когда вы закончите, вы сделаете вывод о возможных типах, используя структурную эквивалентность типов (так называемый тип утки).
PS: в дополнение к выводу типов вы можете взглянуть на «Как история программы может улучшить завершение кода» Ромена Роббса , объясняет, как дальнейшее улучшение автозаполнения в динамических языках с помощью недавно использованной информации и совместной фильтрации.
Так вот как работает абстрактная интерпретация для фрагмента кода, подобного
def groups(array,&block)
groups = Hash.new
array.each { |ea|
key = block.call(ea)
groups[key] = [] unless groups.include? key
groups[key] << ea
}
return groups
end
вы бы начали с
array = { :messages => [], :types => [] }
block = { :messages => [], :types => [] }
, а затем
array = { :messages => [], :types => [] }
block = { :messages => [], :types => [] }
groups = { :messages => [], :types => [Hash] }
, а затем
array = { :messages => [:each], :types => [] }
block = { :messages => [], :types => [] }
groups = { :messages => [], :types => [Hash] }
, а затем
array = { :messages => [:each], :types => [] }
block = { :messages => [:call], :types => [] }
groups = { :messages => [], :types => [Hash] }
key = { :messages => [], :types => [] }
, а затем
array = { :messages => [:each], :types => [] }
block = { :messages => [:call], :types => [] }
groups = { :messages => [:include?,:[]], :types => [Hash] }
group_elements = { :messages => [], :types => [Array] }
key = { :messages => [], :types => [] }
, а затем
array = { :messages => [:each], :types => [] }
block = { :messages => [:call], :types => [] }
groups = { :messages => [:include?,:[]], :types => [Hash] }
group_elements = { :messages => [:<<], :types => [Array] }
key = { :messages => [], :types => [] }
так что в итоге мы можем сделать вывод, что
array
возможно Enumerable
block
возможно Proc
groups
- это Hash
с Array
элементами
key
- это любой объект