Pull to refresh

Comments 31

Так студия-то пока не релизная, кто знает, что там ещё к релизу накрутят.
Ну так и написали бы тогда тоже что-то вроде «C# 6 support preview», а то действительно звучит так, будто уже все готово.
Мы писали об этом, например фрагмент из блогпоста о RTM 9.0:

«Support for C# 6.0. Although the final C# 6.0 language design is not yet clear enough, ReSharper 9.0 already provides support for most of what is defined. New code suggestions help migrate your existing code to more concise C# 6.0...»

Со страницы «What's new in ReSharper»:

«Initial support for C# 6.0»
«Although the feature set for C# 6.0 is not yet finalized, ReSharper 9 already provides support for such new language constructs...»

Возможно, это действительно недостаточно очевидно, что продукт выпускающийся намного раньше официального релиза VS2015 физически не может поддерживать релизную версию языка, потому что ее просто еще не существует. К сожалению, релизить продукт — это сложный процесс, требующих коммунникации между многими людьми, возможно мы действительно потеряли часть информации при подготовки релизных материалов. Мы уточним информацию о поддерживаемом сабсете C# 6.0 на сайте и в блогпостах.
Проверьте вот такой синтаксис:
string s = $"r1={r1} r2={r2}";

Я так понимаю именно такой синтаксис попадёт в релиз.
на этот синтаксис студия выдает ошибку компиляции
Но именно его задокументировали.
Это еще не известно (в таких условиях работаем, ага), но скорее всего именно такой синтаксис попадет в релиз. Вероятно, что вместе с verbatim-интерполяцией:

var path = $@"{programFiles}\MyApp"
Работы много и не всегда ребята успевают внедрять новые фичи. Например в CoffeeScript плагине до сих пор нет поддержки ключевых слов private, public, interface, etc. (они подсвечиваются как ошибки, хотя в реальности это не так), а в PhpStorm нет поддержки всех новых фич php 5.6, например phpdbg (встроенного отладчика), также фича инициализации свойства (или константы класса, точно не вспомню) массивом подсвечивается эррором.

Так что праведное возмущение по поводу «полуподдержки» можно распространить на любой продукт, всего и сразу охватить просто невозможно — давайте вспомним сколько у них продуктов разных ;)
Т.е. вы говорите, что проблема еще хуже: не только в решарпере, но и в других продуктах разработчиков раздражает неправильная подсветка синтаксиса?
В этом случае мне кажется хорошо бы поискать какое то общее решение (позволять пользователю что то типа «add to user dictionary»), иначе вся эта подсветка ситнтаксиса ничего не стоит.

Просто подсветить другим цветом новое ключевое слово — это очень плохое и поверхностное решение. В этом случае у пользователя создастся ложное впечатление, что весь связанный с ним функционал тоже поддерживается — анализ кода, рефакторинг и т.д…
Ок. Давайте рассмотрим ситуацию: сейчас подсветка синтаксиса работает не корректно.
Я вижу два варианта:
1. Ничего не делать, т.е. продолжать подсвечивать корректный синтаксис как ошибка. В этом случае, разработчик быстро перестанет считаться с подсветкой вообще.
2. Добавить возможность что то типа «Add to to user dictionary», что бы разработчик мог бы добавить неподдерживаемые слова в свой словарь с уровнем «предупреждение». В этом случае, разработчик может и дальше доверять подсветке синтаксиса и видеть те конструкции, которые пока не поддерживаюся.

Мне кажется, что второй вариант все-таки меньшее из зол.

Переходное состояние языка, когда некоторые конструкции существуют в неутвержденном виде — крайне редкая и непродолжительная вещь. Если уж человек скачивает бета-версию попробовать, обычно он готов к тому, что что-то может не работать. Так что проблема сама по себе во многом надумана.

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

  1. Не описывает ничего, кроме новых ключевых слов — за бортом оказываются операторы, интерполяция строк, новая семантика первичных конструкторов, инициализаторы свойств, инициализаторы словарей, в общем всё остальное.
  2. Не решает ничего, кроме некорректной подсветки в тексте — тот же nameof будет подсвечен как ключевое слово, но среда разработки по-прежнему не знает, какое выражение допустимо в скобках и что с ним делать в случае рефакторинга.
  3. Переносит ответственность с разработчиков среды и инструментов к ней на конечного пользователя, что в корне неверно.

Если хотите сделать как следует и верите, что имеет смысл опередить разработчиков решарпера — напишите лучше плагин.
Переходное состояние языка, когда некоторые конструкции существуют в неутвержденном виде — крайне редкая и непродолжительная вещь. Если уж человек скачивает бета-версию попробовать, обычно он готов к тому, что что-то может не работать. Так что проблема сама по себе во многом надумана.


Негативное впечатление очень легко заработать и потом трудно исправить. И вместо того, что бы я всему окружению рассказывал бы, какой решарпер крутой и уже поддерживает c# 6, я буду вынужден говорить, что девятка еще глюковата, давайте подождем (хотя объективно для продашена c# 6 и не нужен сейчас).
Или на внутреннем семинаре о фичах c# 6 все будут спрашивать, а почему там что то красненькое такое, а я буду отвечать глюковат релиз 9-ого решарпера.
Так как я запускаю превью студии, то проблемы студии будут игнорироваться, а проблемы релизной версии решарпера нет.

Не описывает ничего, кроме новых ключевых слов — за бортом оказываются операторы, интерполяция строк, новая семантика первичных конструкторов, инициализаторы свойств, инициализаторы словарей, в общем всё остальное.


Тут поднимается вопрос, можно ли реализовать «add to user's dictionary» не только для ключевых слов, но и для других языковых конструкций. Если нельзя — то и говорить не о чем. А вот если можно, то почему бы нет?
Тут вопрос технический. Интересно бы узнать мнение от разработчиков решарпера.

Не решает ничего, кроме некорректной подсветки в тексте — тот же nameof будет подсвечен как ключевое слово, но среда разработки по-прежнему не знает, какое выражение допустимо в скобках и что с ним делать в случае рефакторинга.

Так я и говорю только о подсветке и не прошу рефакторинга.

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

Согласен. Только эти слова я бы переадресовал бы разработчикам решарпера.
Если вы серъезно считаете, что для новых фич языка программирования сложности C# можно сделать что-то типа «Add to user dictionary», то очень глубоко заблуждаетесь.

Новые языковые конструкции надо как минимум попарсить, парсер не может парсить где угодно разный неизвестный «мусор», а потом просто игнорировать его при построении синтаксических деревьев. ReSharper — это не только синтаксический тул, а куда больше семантический. Нельзя просто «добавить» парсинг «a?.B(x)» потому что "?." влияет на control flow граф (а он на dataflow анализы), добавляет множество новых ошибок компиляции, влияет на тип выражения («поднимает» типы-значения до nullable-типов) и так далее (это вообще другая нода AST, не то же самое что «a.B(x)»). Оператор nameof имеет особые правила того, что можно под ним упоминать (которые меняются до сих пор!), а отличить оператор nameof от вызова метода nameof() можно только семантически (так же как с классом «var»).

Я понимаю, что для конечного пользователя выглядит что после релиза R# парни из MS просто поменяли «using System.Console;» на «using static System.Console;», а решарпер этого не поддерживает. А для разработчика тула — это две недели работы, потому что если разобраться, то using static начал открывать не только статические классы, но и любые другие типы + открывать extension-методы. А значит надо отревьювить весь код от вставки using'ов, оптимизации using'ов, форматтера (он умеет using'и на группы разбивать), фич вставки и инлайна using static'ов, ошибок компиляции, инспекций типа redundant qualifier, запретить использование using static в razor/aspx-разметках, прикрутить using static к фиче «Import on paste», использовать возможность импортировать extension-методы из конкретных типов для разрешения конфликтов (открытие целого namespace'а может создавать конфликты с другими extension-методами, теперь можно будет пробовать решать это открывая лишь один using static System.Linq.Enumerable, например). И это только вершина айсберга, я не упоминаю всякие кэши extension-методов и сколько кода надо переписать чтобы добавить импорт extension-методов из конкретных типов :)

К сожалению, R# всегда имеет некоторый разрыв от эталонной реализации языка и мы всегда работаем чтобы свести эту разницу к нулю. В IDE-тулинге невозможно сделать такой механизм, позволяющий просто игнорировать новые конструкции с неизвестной семантикой, по крайней мере для статически типизированных языков.
Слушайте дядю, дядя знает, о чем говорит.
во-первых, спасибо за детальный ответ.

Если вы серъезно считаете, что для новых фич языка программирования сложности C# можно сделать что-то типа «Add to user dictionary», то очень глубоко заблуждаетесь.

вот за это я и люблю хабр, что на одно «глубокое заблуждение» у меня станет меньше :). осовободится место для других.

Вообще то мой вопрос звучал так, можно ли предложить пользователю workaround для того, что бы как то «подавить» проблемы неправильной подсветки кода (для c# 6). Я уверен, что если пофантазировать, можно найти варианты. Может быть они будут не практичны, а может и да.

Интересно, ведь решарпер может знать, что компилятор таки скомпилировал этот код и наверняка, можно получить результаты парсинга. Эта информация не может помочь подумать о каком либо решении проблемы подсветки?

Спасибо за фидбек, действительно в девятой версии решарпера мы не смогли охватить все фичи шестого шарпа.
В основном это связано с тем, что вышеописанные фичи еще не получили окончательный дизайн. Например, для стоковой интерполяции есть вот такие изменения в дизайне: roslyn.codeplex.com/discussions/570292
Однако, мы полагаем, что даже этот дизайн не окончательный. Зачем писать поддержку и тратить время того, что через месяц выбросят?
Ну а баги… Спасибо за фидбек, в ближайшем обновлении уже будет исправлен =)
Проблема в ожиданиях разработчика: вот пока решарпер не был релизным, я спокойней относился к «полуподдежке».
Но в релизной версии я ожидаю или полную поддержку (плюс/минус баги) или явное описание того, что не поддерживается.

Зачем писать поддержку и тратить время того, что через месяц выбросят?

например, что бы Ваши пользователи были еще более довольны, чем сейчас :)
Тут скорее возникает вопрос зачем включать в релизную версию решарпера фичи из превью версии языка? Получается что вы снизили планку качества решарпера. А ведь можно было просто назвать эту версию решарпера бетой или превью или еще как там)
Впрочем, честно написать что не реализовано, в уже сложившейся ситуации — это тоже хороший ход.
а может вообще добавить поддержку c# 6 как фича Resharper Labs (выключенная по умолчанию) или плагин. тогда и вопросов было меньше. или нет?

Тут скорее возникает вопрос зачем включать в релизную версию решарпера фичи из превью версии языка?

я так могу представить, что «релиз» нужен для денег, а поддержка из превью для обката новых возможностей решарпера.
Мы не снижали «планку качества». Поддержка тех или иных конструкций C# 6.0, которые не подверглись изменениями в последнее время и дизайн которых был достаточно устоявшимся, сделана достойного качества. Остальное — особенности эволюции C# 6.0 и Roslyn, на которые мы не можем повлиять.

Не стоит думать, что релиз делается только из-за одной поддержки C# 6.0 и мы сколько угодно можем подгонять release schedule под VS2015, в ReSharper 9.0 множество других возможностей которые мы считаем осмысленным зарелизить сейчас. Сделать поддержку C# 6.0 плагином — нереально, изменения приходится делать по коду всей C#-поддержки, от самого ядра (а от него ависит очень много кода и фич, все приходится ревьювить в условиях нового языка).

Про неподдержанные фичи напишем, спасибо.
Маленький баг в «Use object initializer» вас смутил, а то что сама фича («Dictionary initializers») до сих пор не сделана нормально и семантика не ясна — это наверное нормально…

Например, сейчас сайд-эффект вычисления выражения под инициализатором дублируется для каждого nested-инициализатора. Такого нет больше ни в одном месте языка. Пофиксить обещали полгода назад :)
Маленький баг в «Use object initializer» вас смутил,


Даже ваши люди пометили этот «маленький» баг как критический.

Любое сомнение в правильности кода генерации, на мой взгляд, убивает этот фичер сразу и надолго.
Это особенности багтрекинга в ReSharper :)

Конечный приоритет все равно выберет разработчик, а мне проще починить этот баг, чем выбирать ему приоритет чтобы всех устроил. Поменял на show-stopper, вам так лучше?

Насчет сомнений в фиче — я с вами согласен, ошибки в тулинге достаточно опасны и последствия могут быть печальными. Что еще тут сказать, верифицировать корректность IDE-тулинга еще не научились, значит будем просто чинить :)
вообще то я думал, что Critical это самый высший приоритет :)

Насчет сомнений в фиче — я с вами согласен, ошибки в тулинге достаточно опасны и последствия могут быть печальными. Что еще тут сказать, верифицировать корректность IDE-тулинга еще не научились, значит будем просто чинить :)


Интересно, мне казалось, что на сам рефакторинг можно написать обычные программные тесты. Поэтому меня сильно озадачила такая ошибка.
Можно пояснить, почему этот рефакторинг нужно тестировать через IDE?
Я говорил про программную верификацию корректности рефакторингов и других фич («IDE-тулинга»), каким-нибудь proof assistant'ом :)

Конечно все тестируется обычными модульными и интеграционными тестами (>45 000 тестов на каждый билд) + интеграционными тестами тестами исполняющимися в Visual Studio на куче разных виртуалок в разных конфигурациях.
Т.е. на рефакторинг этого примера
Dictionary<string, int> dictionary3 = new Dictionary<string, int>(); 
dictionary3["X"] = 1; 
dictionary3["Y"] = 2; 

просто не было теста, по причине того, что сама фича еще не очень зарелизина?
Пошерстил тесты, оказалось что разработчик фичи просто не протестировал случаи с несколькими вызовами индексаторов. То есть есть тесты с какими угодно инициализаторами, несколькими параметрами, перегрузками и т.п., но всегда с одним вызовом:

class D {
  public int this[int i, int j] {
    get { return 1; }
    set { }
  }
}

class C {
  public static void Foo() {
    D d = new D(){};
    d[1,2] {caret}= 5;
  }
}


Мы когда-то заимплементили эти инициализаторы вместе с event initializers, а потом последние пришлось выпиливать, с порядком вычисления аргументов инициализаторов было не ясно (давно делали это) — где-то по пути забыли обработать случаи нескольких вызовов… :(
Да, когда этот функционал писался, конечно же это проверялось. Однако, позже, выпиливая эвент инициализаторы, я это случайно поломал и мы не дотестировали фичу.
Прошу прощения, если это доставило много проблем, как я уже говорил выше, мы скоро все поправим =)
constructor, Andrey2008

полезно добавить в анализатор
    public static class Roots
    {
        public const int Misc = 100;
        public const int Managers = 200;
        public const int SaleManagers = 200;
    }
// ...
        public static readonly Dictionary<int, string> KnownNames = new Dictionary<int, string>
        {
                {Misc, "xxx" },
                {Managers, "yyy" },
                {SaleManagers, "zzz" }
        };

При копипасте SaleManagers не сменил id, после чего создание словаря падает с ошибкой. Анализатор может проверять описания словарей и подсвечивать, если есть дублирование ключей.
Sign up to leave a comment.

Articles