Компания
302,14
рейтинг
19 июля 2013 в 16:14

Разработка → ReSharper 8

Привет, Хабр!

Вы уже наверное догадались, о чем этот пост. Да-да, мы рады представить вашему вниманию свежий ReSharper 8, наш плагин для повышения производительности и качества кода при разработке в Visual Studio. Благодаря участию в партнерской программе Microsoft Visual Studio нам удалось оперативно привести ReSharper 8.0 в соответствие с недавно объявленной версией Microsoft Visual Studio 2013 Preview. Теперь продукт поддерживает целых пять версий Visual Studio, включая 2005, 2008, 2010 и 2012. Когда произойдет окончательный выпуск Visual Studio 2013, при необходимости будет выпущено поддерживающее его обновление для ReSharper.



«Восьмерка» включила в себя улучшения и нововведения в следующих областях:
  • Автодополнение кода;
  • Навигация;
  • Поддержка XAML;
  • Поддержка CSS;
  • Новые рефакторинги;
  • Новый механизм коррекции ошибок «fix in scope»;
  • Шаблоны для создания наборов файлов;
  • Архитектурные инструменты в ReSharper;
  • Упрощение работы с расширениями.

Кроме того, ReSharper 8 выходит за рамки Visual Studio: теперь мы предоставляем бесплатный автономный инструмент с сотнями инспекций кода, доступных в ReSharper, а также функцией поиска дубликатов в коде. Новый продукт под названием ReSharper Command Line Tools можно интегрировать с вашим Continuous Integration сервером или системой контроля версий.



Автодополнение кода



Механизм автодополнения кода, который поставляет ReSharper, является более мощным аналогом «студийного» IntelliSense, и в ReSharper 8 этот механизм претерпел ряд улучшений:

Автодополнение для неимпортированных типов теперь не показывается, как отдельное синее окошко – этот механизм просто включен в список автодополнения:


Выбирая одну из опций, вы не только получаете возможность добавить тип, но ReSharper также добавляет using-директиву в файл. Этот механизм работает везде: просто используйте типы, а ReSharper поможет вам их заимпортировать:


Помимо этого, многие механизмы «обычного» автодополнения теперь предлагают еще несколько «умных» вариантов – например, если вы создаете коллекцию, ReSharper предложит вам выражение по инициализации этой коллекции первым в списке автодополнения:


Кардинально новая фича автодополнения в ReSharper 8 — это двойное автодополнение (double completion). Идея простая – можно нажимать клавиши автодополнения более одного раза, и каждый раз список автодополнения будет расширяться новыми элементами. Например, умное автодополнение для класса покажет вам все подходящие по типу элементы,


но если нажать Ctrl + Alt + Space еще раз, то ReSharper предложит все варианты «второго уровня», т.е. все возможности получить строковые типы путем вызова различных методов на членах класса, в том числе и тех, которые сами по себе string не возвращают:


Двойное автодополнение можно использовать бесконечно, каждый раз удлинняя цепочку вызовов.
Также доступно двойное импортное автодополнение (double import completion). Если попытаться добавить тип, который недоступен (т.е. проект не имеет ссылок ни на одну сборку содержащую подходящий тип), то ничего не получится:


Но если нажать сочетание клавиш еще раз (Shift + Alt + Space), то ReSharper покажет вам следующий список:


Выбрав один из элементов списка, вы сразу сделаете три вещи: добавите ссылку на нужную сборку в текущем проекте, добавите директиву using в текущий файл, и получите замену названия типа (если вы, например, использовали сокращение).

Еще одна новая возможность – это генеративное автодополнение (generative completion). Самый простой пример этого – генерация заглушек для перегруженных методов. Достаточно написать ключевое слово override и ReSharper предложит вам все возможные варианты:


Аналогичная ситуация возникает, когда вы хотите инкапсулировать поле: все, что нужно, так это написать имя свойства, которое соответствует этому полю, и ReSharper сам предложит вам сгенерировать свойство-обертку. С учетом использования, он также может предложить вам свойство «только для чтения»:


Ну и наконец, упростился механизм генерации конструкторов – сокращения ctorf, ctorp и ctorfp позволяют прямо в коде создать конструктор с инициализаций всех полей, свойств или и того и другого:


Еще одно нововведение – это автодополнение для флагов форматирования (formatting specifiers). Идея в том, что вызывая ToString() на каком-нибудь стандартном типе из .NET, ReSharper помогает вам понять, какие элементы форматирования существуют именно для этого типа, для чего они нужны, а также, как может выглядеть конечный результат подобного форматирования:


Автодополнение также работает внутри спецификации форматирования в вызове String.Format():


Навигация


В наших попытках упростить механизмы навигации мы создали новый механизм под названием Go to Everything («перейти к чему угодно»). Идея в том, что этот механизм осуществляет поиск одновременно по всем файлам, типам и элементам типов:


Также мы добавили возможнсть переходить на определенную строку в файле – для этого просто нужно написать ее номер:


Кроме этого, ReSharper поддерживает механизм навигации к дженерик-подстановкам, т.е возможность найти где и какими типами замещены generic-параметры:


Помимо этого, навигация на исходный код для декомпилированных типов перенесет вас не в Solution Explorer, а уже в Assembly Explorer. Для этого можно нажать на Shift + Alt + L или просто выбрать соответствующий элемент контекстного меню:


Поддержка XAML



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


Автодополнение также работает, например, для определения свойств, которым задается стиль:


Также, ReSharper производит автодополнение в атрибутах x:Shared и xml:space:


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


Если стиль переопределяет свойство из другого стиля, ReSharper показывает иконку для навигации к базовому опеределению:


Если же определение свойства дуплицированно, то ReSharper предложит его удалить:


И, конечно, если применть к контролю стиль а потом начать дублировать свойства, то ReSharper пожалуется и на это:


Также, для поддержки стилей у нас появились новые рефакторинги. Первый рефакторинг — Extract Style для вытаскивания стилей из инлайн-определения:


Вызвав этот рефакторинг, появится диалог, позволяющий выбрать, какие свойства вы ходите вынести в стиль, и где этот стиль разместить:


Если вы потом решите добавить какие-то свойства в элемент, к которому применен тот или иной стиль, добавить новые свойства в этот же стиль проще простого:


Помимо этого, появились рефакторинги для «вытаскивания» и перемещения ресурсов, определенных в XAML. Этот рефакторинг позволяет вытащить, например, строку:


Причем анализ однородности элементов даст вам вытащить либо один инстанс ресурса, либо все идентичные элементы:


Выбрав элементы, ReSharper покажет вам диалог где можно выбрать, как будет называться ресурс и где он будет размещен:


Теперь можно выполнять перемещение ресурсов по элементам сочетанием клавиш Ctrl + Alt + Shift и клавиш вправо/влево:


Также доступен рефакторинг инлайнинга ресурсов (inline XAML resource), который позволяет, наоборот, вытащить ресурс и вставить его «как есть»:


Вызов этого рефакторинга тоже имеет несколько настроек:


Ну, и наконец, появилось еще несколько возможностей, в частности, поддержка атомарного переименования «зависимых свойств» (а также событий), удаление неиспользованных определений пространств имен, а также контекстные действия для произольного удаления markup-свойств.

Поддержка CSS



Поддержка CSS в ReSharper 8 распространяется не только на CSS-файлы, но также на использование CSS в других языках, таких как JavaScript и C#. Автодополнение в этих языках доступно для известных CSS аттрибутов:



А также для имен классов:



Или для имен элементов:



Для автодополнения также используются live templates — шаблоны, которые позволяют эффективней определять значения. Например, при определении ширины элемента, представлены два шаблона: length и percentage:


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


Также в ReSharper 8 мы производим проверку CSS на соответствие той или иной версии, а также на совместимость с популярными веб-браузерами:


Настроив, например, CSS на версию 1.0, использование несовместимого атрибута будет воспринято как ошибка:


Помимо этого, ReSharper предлагает контекстные действия для различных представлений цветов – либо как именованые сущности, либо через функции rgb() или hsl():


Наконец, для CSS появилась поддержка таких вещей, как @keyframe, @view-port и @page.

Новые Рефакторинги



В ReSharper 8 у нас появилось три новых рефакторинга. Первый – Inline Parameter позволяет заменить параметр в методе на тот ли иной литерал. Например, в следующем коде

мы можем поменять аргумент value на значение 400:


Если вариантов значения для параметра несколько, то ReSharper спросит какой из них вы хотите использовать:


ReSharper производит очень глубокий анализ использования параметров. В случае, если пользователь должен заменить параметр другим, ReSharper предложит подобный вариант:


Второй рефакторинг называется Pull Parameter и позволяет, в случае если в метод добавляется новый параметр, выбрать один из вариантов замещения этих вызовов на основе всей цепочки вызовов:


И наконец третий рефакторинг — Move Instance Method позволяет передвинуть метод из одного класса в другой, при этом сохранив валидность всех вызовов.

Fix in Scope



Fix in Scope или «пофиксить в определенной зоне видимости» – это возможность применить фикс определенного типа не только к конкретному элементу в коде, но также к файлу, проекту или всему решению:


Шаблоны для создания наборов файлов



В ReSharper 8, механизм Live Templates был расширен, чтобы поддержать генерацию сразу нескольких файлов из одного темплейта. Создавать эти шаблоны просто – для этого, в редакторе шаблонов появились две кнопки добавления дополнительных файлов:


Файл можно добавить или из существующего шаблона, или создать новый. В этом случае, редактор «делится» на несколько частей для редактирования файлов:


Все файлы многофайлового шаблона могут использовать общие переменные, что существенно упрощает создание, например, нескольких разных слоев приложения:


Архитектурные инструменты в ReSharper



Нам, как и многим другим разработчикам, которые работают с большими решениями в Visual Studio, хочется видеть, как проекты зависят друг от друга. К сожалению, представление зависимостей в исходном коде ReSharper, которое строит Visual Studio Ultimate, довольно сложно понять:


В итоге мы решили сделать свой собственный инструмент с преферансом и поэтессами для отображения зависимостей в проекте, который также позволяет сохранять и сравнивать состояние архитектуры решения в разные моменты времени.

Как же это работает? Открыв в Visual Studio свое решение, выберите в меню команду ReSharper|Architecture|Build Architecture Graph:


ReSharper проанализирует ваше решение и отобразит диаграмму зависимостей всех его проектов. Характерно, что компилировать проекты для этого не нужно:


Расположение элементов графа зависимостей определяется автоматически таким образом, чтобы добиться их оптимального представления. Если при этом функция Show Code Metrics включена (а по умолчанию она включена), то при построении графа зависимостей анализ связей будет происходит асинхронно: ReSharper будет анализировать все решение и показывать степень связанности проектов (количество ссылок).

Всё это происходит в отдельном потоке, поэтому пока ReSharper делает свою работу, вы можете продолжать писать код.

В представлении присутствует два типа связывающих стрелок: черные стрелки показывают действующие ссылки на другие проекты, в то время как серые стрелки обозначают неиспользуемые ссылки, которые можно удалять, не поломав при этом билд. Масштаб архитектурной диаграммы можно выбирать в Solution Explorer: например, если вы выделите только папку с несколькими проектами, только эти проекты и будут участвовать в диаграмме. Также можно отдельно выбирать (поэлементно), какие проекты будут включены в представление, просто установив нужный флажок:


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


Также есть несколько вариантов группировки проектов: None (не группировать проекты), Solution folders (группировка по папкам проектов) и File structure (группировка по папкам, в которых физически расположены файлы).
На панели инструментов также есть следующие кнопки:

  • Collapse Graph и Expand Graph позволяют свернуть или развернуть ту область, в которой используется группировка. Свернутая группа выглядит следующим образом:

  • Сгруппированные проекты также можно свернуть или развернуть двойным щелчком на иконке + или -, соответственно.
  • Кнопка Show/Hide Code Metrics позволяет скрыть или показать метрики, связанные с кодом проектов. Эти метрики показывают используемые и неиспользуемые ссылки (черные и серые стрелки соответственно):

  • Для того чтобы посмотреть, где эти ссылки вызываются, просто щелкните правой кнопкой мыши по индикатору и выберите Show Usages…
  • Кнопка Show Transitive References позволяет отображать не только прямые, но и транзитные связи, то есть в добавление к отображению A → B → C на диаграмме появится A → C. Это может привести к очень плотному, похожему на радиоэлектронную схему, представлению:

  • Команда Save Architecture Graph позволяет сохранить граф в файл.
  • Команда Show Diff показывает различие между двумя архитектурными графами. Эту функцию также можно вызвать из верхнего меню (даже когда решение не загружено):



Благодаря тому, что архитектурные графы можно сохранять в файл, пользователь может видеть изменения в архитектурной диаграмме в процессе развития программы. Далее представлен пример того, как ReSharper показывает изменения при сравнивании архитектурных снэпшотов «до» и «после»:


Здесь показано представление развития одной из подсистем самого ReSharper’а. Красным обозначаются удаленные части решения, а темно-зеленым — вновь добавленные части. Аналогичным образом обозначаются новые и удаленные ссылки.
Контекстное меню, знакомое по Solution Explorer, можно также вызвать в режиме Architecture View, щелкнув правой кнопкой мыши на соответствующем узле.


Упрощение работы с расширениями



У Решарпера есть своя экосистема расширений, и для ReSharper 8 мы существенно упростили механизм поиска этих расширений. Задействовав NuGet и разместив каталог расширений, скачать и установить плагин теперь можно в один клик:


Заключение



Это пожалуй все, о чем хотелось рассказать в этой статье. Будем рады вашим вопросам. Узнать больше и загрузить бесплатную 30-дневную пробную версию ReSharper 8.0 можно, посетив страницу продукта.

Программируйте с удовольствием!
Команда JetBrains.
Автор: @beenom
JetBrains
рейтинг 302,14

Похожие публикации

Комментарии (21)

  • +3
    ОБМ. Да это просто праздник какой то.
  • +2
    Большое спасибо за релиз, Go to everything замечательный!

    В тему автокомплита — мне очень нравятся Live templates и особенно их регионозависимость, но я почему-то не могу переносить автокомплит в решарпере и использую студийный. Можно ли как-то полноценно использовать темплейты со стандартным комплитом? Вызывать вставку через хоткей — не самое приятное занятие.
    • +2
      Увы, такой возможности нет. Ctrl+E,L (в студийной раскладке) или Ctrl+J (IntelliJ-раскладка) — единственный вариант вставки шаблонов в обход IntelliSense.

      А вы попробуйте автокомплит в восьмерке — там многое изменилось, вдруг вам понравится?
  • 0
    А как с апгрейдом недавно купивших решарпер 7? Снова платить или действует годовая подписка на обновления?
    • +1
      Гляньте в их блоге чтобы точнее, но кажется они отвечали так — для персонального использования апгрейд бесплатен для те, кто купил после 1 июня, для коммерческих бесплатен, если действует годовая подписка на обновления.
      • +2
        Совершенно верно.

        Условия апгрейда академических лицензий аналогичны персональным.

        Дополнительно отмечу, что всем клиентам персональной и академической категорий, кто купил или обновился до версии 7 в мае этого года, рекомендуется написать в отдел продаж и попросить скидку на обновление — как правило, они её предоставляют.
  • 0
    А как же ваше обещание про добавление поддержки С++ в 8-ой версии?
    • +4
      Предже всего, хочется в очередной раз подчеркнуть что поддержка С++ не будет включена в ReSharper 8 потому что она еще «сыровата» для полноценного продакшн-релиза.

      (Поддержка C++ в ReSharper)

      Вы это обещание имеете в виду, или какое другое?
      • 0
        Да, видимо подзабыл малость это заявление.
  • +1
    На правах примечания: скриншоты в разделе про архитектурные инструменты снимались на предрелизной версии ReSharper 8.0. С тех пор оформление графов зависимостей существенно изменилось. Чтобы посмотреть, как они выглядят сейчас, ознакомьтесь с этим видео.
  • 0
    Пофиксили ли property with backing field, которые при рефакторинге создавались не рядом, а вверху класса?
    • 0
      Вы имеете в виду context action «To property with backing field»? В каком языке?
      • 0
        C#
        В 6 версии емнип когда конвертилась auto property to property with backing field, то приватное поле ставилось рядом с пропертей. В 7 появилось упорядочивание, и приватное поле начало уезжать в начало класса, что чертовски неудобно.
        • +3
          1. Касаемо «пофиксили» — поля стали создаваться рядом с другими полями не из-за какого-либо бага, а из-за пачки реквестов пользователей, которым надоело самим таскать поля после контекстных действий. Исследовав ситуацию с предпочтениями расположения полей в layout'е классов в различных доступных солюшенах пришли к выводу, что расположение поля рядом со свойством — куда менее распространенный кейс, чем группировка полей вместе.

          2. Как только возникают подобные ситуации (http://xkcd.com/1172/) — помогает завести нам реквест или проголосовать за существующий. Где-то я такой реквест видел, наверное прийдётся сделать настроечку на 8.1, чтобы были счастливы все. Простите, если это доставило так много неудобств.

          3. От меня лично: от схемы layout'а классов «поля рядом с их свойствами» на самом деле лучше отказаться, так как никто не может толком ответить — где располагать поля, не привязанные к свойствам? Большинство располагают в начале класса, но почему тогда внезапно имеет смысл размещать другие поля рядом со свойствами — не понятно. Совсем не понятно, где размещать поле, если оно может рассматриваться как «backing field» сразу нескольких свойств. Само понятие — «backing field» — очень сложно даже лишь пытаться формализовать (public List XS { return xs ?? (xs = new List()); } — тут «xs», это «backing field»? А если в акцессорах встречаются несколько полей? И ещё очень много чего магического может быть написано в акцессорах). В решарпере минимум эвристик на эту тему. Подобный class layout невозможно выразить в нашем code cleanup для автоматического реордеринга членов классов, не смотря на сложность языка описания class layout'а. Ну и из личного опыта — когда весь стейт типа в одном месте, это удобнее, чем внезапно обнаруживать поля где-нибудь между методов в совсем неожиданных местах.
          • 0
            Для меня это самое backing field — это то что было auto property (public T Prop { get; set; }), а захотелось инициализацию, чтобы не мучиться с null. Всякое страшное использование нескольких пропертей на одном поле или проперти со страшной логикой — от лукавого и не про то.

            Опять же имхо: когда близкие по семантике члены класса собраны вместе — это удобно, потому что когда правишь какой-то функционал, обращаешься именно к семантическому куску (ну например реализацию интерфейса удобно даже в #region заворачивать). Я когда-то пытался использовать «структурный» layout с группировкой по формальным признакам языка и понял, что это мне мешает, вместо того чтобы помогать. Бегание по всему файлу отнимает время, особенно если файл большой.
            • 0
              Зачем вам бегать по файлу, если вы пользователь решарпера?
              Интереса ради, Go to File Member, Go to Usages of Symbol, Alt+вверх/вниз — вы всем этим пользуетесь?
              • 0
                Нет, этим не пользуюсь.
                Вместо этого у меня Go to Declaration (aka Ctrl+Click) и Find Usages. Наверное, это потому что я не помню, как у меня называются члены класса.
                А никуда не ходить мне удобней, чем куда-то ходить, пусть даже это и просто.
          • 0
            Прошу прощения что отвечаю так поздно — только сейчас в очередной раз загуглив решение проблемы увидел комментарий. Дело в том что XAML разработчикам при создании ViewModel очень много приходится создавать property with backing field только для того что бы вызывать OnPropertyChanged для этого поля или дополнительно для нескольких полей. И таких полей приходится делать очень много. И при этом рефакторинг значительно усложняется если решили что это поле должно быть в другой VM. Вместо того что бы «вырезать»-«вставить» получаем «вырезать» «вставить» вернуться, найти это поле где оно было «вырезать», «вставить». Если решили удалить это проперти совсем — можно запросто забыть удалить поле наверху и т.д. и т.п. Да при построении логики это может быть и удобно когда поле генерируется на верху, но при активной работе с VM (а эта чуть ли не львиная доля работы для тех кто работает с XAML) это страшно неудобно и раздражает. То же самое касается Dependency Property. А в целом решарпером очень доволен — один из тех продуктов за который не жалко потраченных денег, но вот это «фича», которая по мнению JetBrains сделала нашу жизнь гораздо проще, субъективно снижает ценность продукта.
  • +1
    Всё это происходит отдельном потоке, поэтому пока ReSharper делает свою работу, вы можете продолжать писать код.

    Когда же мы будем пить кофе, а Решарпер будет писать код, «в отдельном потоке»? :) Спасибо, замечательную тулзу!
  • 0
    У меня в финальной версии все так же есть глюк, что в некоторых классах в саджесте нет полей и методов текущего класса. Локализовать к сожалению не могу :(
    • 0
      Если таки сможете, напишите, пожалуйста, в трекер.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка