Intellisense для динамических языков

Я ищу различные подходы для поддержки некоторого уровня intellisense на динамически типизированном языке. С тех пор intellisense информация основан на информации о типе, существуют свойственные трудности при реализации этого для динамических языков.

Вы знаете, что какие-либо алгоритмы или методы реализуют его?

5
задан gunr2171 21 July 2015 в 15:05
поделиться

4 ответа

Вам нужно написать абстрактный интерпретатор , который выполняет код со значениями типов. Таким образом, вы переходите со своим абстрактным интерпретатором через 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 => [] }

так что в конечном итоге мы можем сделать вывод, что

  • массив , возможно, Перечислимый
  • блок , возможно, Proc
  • группы - это Хэш с Массив элементы
  • ключ - любой объект
7
ответ дан 14 December 2019 в 04:39
поделиться

Я бы скачал исходники плагина Groovy для затмения, он обладает интеллектом (насколько это возможно), и считаю Groovy хорошим образцом дианамического языка с динамической опечаткой

.
1
ответ дан 14 December 2019 в 04:39
поделиться

Легко, нужно добавить только один дополнительный шаг - вывод типа . После этого вы знаете информацию о типе и можете кое-что подсказать пользователю.

.
0
ответ дан 14 December 2019 в 04:39
поделиться

Обратите внимание, что "динамический язык" и "язык с динамическим набором" не обязательно одно и то же.

То, как Microsoft справляется с этим в интеллигенции для Javascript (VS2008), заключается в том, что она, в меру своих возможностей, приходит к выводу, какой тип var в настоящее время имеет в своем распоряжении. Если/когда это изменится, следующие ссылки на var будут представлять опции для обновленного типа.

.
0
ответ дан 14 December 2019 в 04:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: