bsl-language-server
bsl-language-server copied to clipboard
Изменение параметра сслычного типа переданного по значению
Нельзя
Функция СвернутаяТз(Знач Тз)
Тз.Свернуть();
Возврат Тз;
КонецФункции
Нужно
Функция СвернутаяТз(Знач Тз)
СвернутаяТз = Тз.Скопировать();
СвернутаяТз.Свернуть();
Возврат СвернутаяТз;
КонецФункции
А теперь как это угадать без базы контекстов... Или что можно\Нельзя делать по Знач
Для @stepa86 можно сделать отдельное. "Нельзя присваивать по знач"
Пример не очень правильный, т.к. Свернуть() это процедура, а не функция.
Простейший вариант со Знач
Функция ЧтоТоПосчитать( Знач НекоторыйПараметр )
НекоторыйПараметр = ЧтоТоСделать( НекоторыйПараметр ); // Тут ругаться на присвоение параметру
ЧтоТоЕщеПоделать( НекоторыйПараметр ); // Тут ругаться, т.к. параметр в процедуре указан не как Знач
новаяПеременная = ЧтоТоДополнительноПолучитьПравильно( НекоторыйПараметр );
Возврат новаяПеременная;
КонецФункции
Функция ЧтоТоСделать( Знач НекоторыйПараметр )
НекоторыйПараметр = НекоторыйПараметр + 1; // Тут ругаться на присвоение параметру
Возврат НекоторыйПараметр;
КонецФункции
Процедура ЧтоТоЕщеПоделать( НекоторыйПараметр )
НекоторыйПараметр = НекоторыйПараметр - 5;
КонецПроцедуры
Функция ЧтоТоДополнительноПолучитьПравильно( Знач НекоторыйПараметр )
Возврат НекоторыйПараметр + 100500;
КонецФункции
Пример не очень правильный, т.к. Свернуть() это процедура, а не функция.
Да, спасибо исправил
Простейший вариант со Знач
Функция ЧтоТоПосчитать( Знач НекоторыйПараметр ) НекоторыйПараметр = ЧтоТоСделать( НекоторыйПараметр ); // Тут ругаться на присвоение параметру ЧтоТоЕщеПоделать( НекоторыйПараметр ); // Тут ругаться, т.к. параметр в процедуре указан не как Знач новаяПеременная = ЧтоТоДополнительноПолучитьПравильно( НекоторыйПараметр ); Возврат новаяПеременная; КонецФункции Функция ЧтоТоСделать( Знач НекоторыйПараметр ) НекоторыйПараметр = НекоторыйПараметр + 1; // Тут ругаться на присвоение параметру Возврат НекоторыйПараметр; КонецФункции Процедура ЧтоТоЕщеПоделать( НекоторыйПараметр ) НекоторыйПараметр = НекоторыйПараметр - 5; КонецПроцедуры Функция ЧтоТоДополнительноПолучитьПравильно( Знач НекоторыйПараметр ) Возврат НекоторыйПараметр + 100500; КонецФункции
к сожалению, ВСЕ варианты, указанные в этом примере, это ложные срабатывания. практически во всех вариантах идет изменение переданного параметра значением, рассчитанным из этого же параметра.
а это не является ошибкой, а довольно часто делается в коде.
Например,
Процедура Метод(Знач Строка)
Строка = СокрЛП(Строка); // не является ошибкой
КонецПроцедуры
Правильно учитывать только те случаи, когда параметр меняется на выражение, которое не зависит от этого параметра.
Процедура Метод(Знач Строка)
Строка = СокрЛП(ДругаяСтрока); // вот тут явно подозрительно
КонецПроцедуры
@Stepa86 @asosnoviy @theshadowco @nixel2007 что скажете?
Какая разница из-за чего меняется параметр, если он не должен меняться?
Вот в этом примере есть ошибка или нет? А когда речь заходит про коллекции? А когда речь заходит про клиент-серверное взаимодействие?
&НаКлиенте
Процедура Команда1(Команда)
текСтр = "123";
Метод(текСтр);
Сообщить(текСтр);
КонецПроцедуры
Процедура Метод(Знач Строка)
Строка = Строка + Строка;
КонецПроцедуры
Мое мнение - если параметр пришел со Знач - нехер его трогать. Безопаснее и предсказуемее будет.
@Stepa86 в указанном тобой коде, конечно, ошибка, но заставляя диагностировать любое изменение Знач-параметра ты просто поймаешь кучу ФП
я зря не расширил свой пример. исправляюсь
Процедура Метод(Знач Строка)
Строка = СокрЛП(Строка); // не является ошибкой, т.к. далее переиспользование этого значения
ИспользованиеСтрокиБезПробелов ( Строка );
КонецПроцедуры
вот такой код часто-часто можно встретить. многие так пишут, это как раз и удобно при использовании Знач-параметра. заводить новую переменную - оверхед ИМХО.
ну и раз есть расхождения, значит, правило точно должно быть параметризуемым.
например, параметр булевый "Ловить любое исправление Знач-параметра" - по умолчанию Ложь
если Истина, ловим любое, как ты предлагаешь если Ложь, ловим изменение параметра выражением, которое не зависит от этого же параметра.
зы на всякий случай - у меня есть опыт использования моего вариант правила, ловятся действительно подозрительные места.
@Stepa86 Я реализовал соседний ишью #1834
- ПР https://github.com/1c-syntax/bsl-language-server/pull/2810
- выдаются замечания на изменение параметра, передаваемого по значению
- есть отличие от обсуждаемого в текущем ишузе варианта - изменение вида
Параметр = Выражение(Параметр)
пропускаются,- т.к. я уже писал, что это довольно обычная практика и будет многовато ФП.
- есть отличие от обсуждаемого в текущем ишузе варианта - изменение вида