Приведите JSON в PowerShell с правильным автозаполнением (IntelliSense) - PullRequest
1 голос
/ 03 апреля 2019

Есть ли способ, чтобы автозаполнение IntelliSense в Visual Studio работало правильно, когда я читаю файл json и преобразую его в PowerShell, например:

$config = Get-Content "SOME_PATH" | ConvertFrom-Json
$config.attribute1 

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

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

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

В настоящее время IntelliSense не делает этого.

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

Запустив его в терминале и загрузив в память, вы явно указываете IntelliSense, что вы используете, а затем он теперь «знает» об объекте и может затем правильно предложить правильные свойства и атрибуты.

Как предполагает @ mklement0, использование сочетания клавиш F8 будет удобно выполнять текущую строку / выделение в интегрированном терминале, что приведет к загрузке объекта в память, и позволит вам использовать IntelliSense в редакторе.

1 голос
/ 04 апреля 2019

В дополнение к полезный ответ HAL9256 :

Сначала немного справочная информация ;найдите рабочее решение в нижнем разделе.

IntelliSense для переменных в коде Visual Studio работает, если их тип:

  • явно объявлен (например, [datetime] $var = ...)
  • или может быть выведено из назначенного значения.

Если назначение на основе команды (вызов командлета, функции, скрипта), тип может быть выведен только из команд с явно определенными типами вывода :

  • многие, но далеко не все, командлеты объявляют свои типы вывода
  • функции и сценарии должны использовать атрибут [OutputType(<type>)].

Кроме того, с невзрачным [pscustomobject] типом , возвращаемым ConvertFrom-Json - который не имеет присущих свойств, только те, которые добавляются по требованию;«мешок свойств» - IntelliSense вы получите только:

  • , если переменная была назначена из пользовательского объекта литерал (например, $var = [pscustomobject] @{ one = 1; two = 2 })
  • , если вы приведете пользовательский объект к определенному типу , предполагая, что экземпляры этого типа могут быть созданы из свойств пользовательского объекта, что упрощает PowerShell - смотрите этот ответ .

Решение с пользовательским классом (PSv5 +)

IntelliSense кода Visual Studio (через расширение PowerShell) распознает членовэкземпляры пользовательских классов PS , определенные с помощью оператора PSv5 + class .

Таким образом, вы можете использовать пользовательский класс для отражения структуры загружаемого объекта JSON и для преобразования [pscustomobject] "пакетов свойств"возвращается ConvertFrom-Json экземпляру этого класса в виде cast .

Примечание: присущее этому подходу ограничение заключается в том, что ваш класс должен предвидеть всеимена свойств, которые содержат базовые объекты JSON, и эти два свойства должны быть синхронизированы ;в противном случае:

  • , если имя свойства изменит на стороне JSON, ваш код будет прерываться , если определение класса не будет соответствующим образом обновлено.
  • если новые свойства будут добавлены на стороне JSON, они будут недоступны, если определение класса не будет соответствующим образом обновлено.

class определения могут быть либо:

  • , непосредственно встроенный в скрипт
  • , импортированный из модулей с помощью оператора using module (обратите внимание, что использование Import-Module не не загружаетклассы модуля).

Для реализации данного решения вы можете использовать определение class одним из двух способов:

  • (a) Определитьclass непосредственно в вашем скрипте, который соответствует структуре объектов JSON, и приведите экземпляр [pscustomobject], возвращенный из ConvertFrom-Json, к этому типу;переменная, назначенная таким образом, поддерживает IntelliSense.

  • (b) Обернуть функцию загрузки JSON в модуль, который выполняет описанное выше внутри модуля, и передать экземпляр class изфункция, которая объявляет [OutputObject()] того же типа;код, который импортирует этот модуль с using module, затем получит IntelliSense для переменных, которые захватывают выходные данные этой функции.

Простая демонстрация (a):

# Define a class whose properties mirror the underlying JSON.
class Config {
  $foo
  $bar
}

# Load the JSON and cast the resulting [pscustomobject] to the class.
# Note: This cast only works if the JSON object's set of properties 
#       is either the same as that of the [Config] type or a subset of it.
[Config] $config = '{ "foo": "bar", "bar": 42 }' | ConvertFrom-Json

# Variable $config supports IntelliSense, because its is now known
# as type Config.
$config. # shows list of properties
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...