1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2024-11-28 09:33:06 +02:00

#385 Проверка имени переменной (#1253)

* #385 Реализация стандарта 454 - проверка имени переменной
This commit is contained in:
Vadim Goncharov 2023-03-20 13:45:09 +03:00 committed by GitHub
parent 1074474016
commit bb151bf321
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 353 additions and 0 deletions

View File

@ -25,6 +25,7 @@
- Использование устаревшего метода Найти
- Отсутствует комментарий к экспортной процедуре (функции)
- Документирующий комментарий не содержит секцию "Описание" для экспортной процедуры (функции)
- Проверка корректного наименования переменных
#### Запросы

View File

@ -0,0 +1,28 @@
# Rules for variable names generation
1. To name a variable, use conventional terms related to the respective subject area so
that the variable's name would be descriptive and convey its purpose to the reader.
2. Variable names mustn't contain spaces, even when it is composed of a few words.
Each word in a variable name starts with a capital letter, including pronounces and prepositions.
3. Variable names mustn't start with an underscore.
4. Variable names must contain more than one character, except for loop counters.
It is allowed to assign loop counters with single-character names.
5. Name Boolean variables so that the name would convey the true state of the variable.
## Invalid variable name examples
```bsl
arrOfAtrribute, _SetTypeDoc, nS
```
## Correct variable name examples
```bsl
Var DialogWorkingCatalog;
Var NumberOfPacksInTheBox;
NewDocumentRef;
```
## See
- [Rules for variable names generation](https://kb.1ci.com/1C_Enterprise_Platform/Guides/Developer_Guides/1C_Enterprise_Development_Standards/Code_conventions/Module_formatting/Rules_for_variable_names_generation/)

View File

@ -0,0 +1,28 @@
# Правила образования имен переменных
1. Имена переменных следует образовывать от терминов предметной области таким образом, чтобы из имени
переменной было понятно ее назначение.
2. Имена следует образовывать путем удаления пробелов между словами. При этом, каждое слово в имени
пишется с прописной буквы. Предлоги и местоимения из одной буквы также пишутся прописными буквами.
3. Имена переменных запрещается начинать с подчеркивания.
4. Имена переменных не должны состоять из одного символа. Использование односимвольных имен переменных
допускается только для счетчиков циклов..
5. Переменные, отражающие состояние некоторого флага, следует называть так, как пишется истинное значение этого флага.
## Примеры некорректных имен переменных
```bsl
массРеквизитов, _СоотвВидИмя, нС
```
## Примеры корректных имен переменных
```bsl
Перем ДиалогРаботыСКаталогом;
Перем КоличествоПачекВКоробке;
НовыйДокументСсылка;
```
## См.
- [Правила образования имен переменных](https://its.1c.ru/db/v8std#content:454:hdoc:3)

View File

@ -347,6 +347,10 @@
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.DeprecatedProcedureOutsideDeprecatedRegionCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.VariableNameInvalidCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.UsingFormDataToValueCheck">

View File

@ -434,6 +434,14 @@ final class Messages
public static String LockOutOfTry_Method_lock_out_of_try;
public static String VariableNameInvalidCheck_description;
public static String VariableNameInvalidCheck_message_variable_length_is_less_than;
public static String VariableNameInvalidCheck_param_MIN_NAME_LENGTH_PARAM_title;
public static String VariableNameInvalidCheck_title;
public static String VariableNameInvalidCheck_variable_name_is_invalid;
public static String VariableNameInvalidCheck_variable_name_must_start_with_a_capital_letter;
public static String VariableNameInvalidCheck_variable_name_starts_with_an_underline;
static
{
// initialize resource bundle

View File

@ -0,0 +1,164 @@
/*******************************************************************************
* Copyright (C) 2023, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
* Vadim Goncharov - issue #385
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.DECLARE_STATEMENT;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.STATIC_FEATURE_ACCESS;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.VARIABLE;
import static com._1c.g5.v8.dt.mcore.McorePackage.Literals.NAMED_ELEMENT__NAME;
import java.text.MessageFormat;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.xtext.EcoreUtil2;
import com._1c.g5.v8.dt.bsl.model.DeclareStatement;
import com._1c.g5.v8.dt.bsl.model.ExplicitVariable;
import com._1c.g5.v8.dt.bsl.model.ForStatement;
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
import com._1c.g5.v8.dt.bsl.model.Variable;
import com.e1c.g5.v8.dt.check.CheckComplexity;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.BasicCheck;
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.e1c.v8codestyle.check.StandardCheckExtension;
import com.e1c.v8codestyle.internal.bsl.BslPlugin;
/**
* Check that variable name is correct.
* @author Vadim Goncharov
*/
public class VariableNameInvalidCheck
extends BasicCheck
{
private static final String CHECK_ID = "bsl-variable-name-invalid"; //$NON-NLS-1$
private static final String MIN_NAME_LENGTH_PARAM_NAME = "minNameLength"; //$NON-NLS-1$
private static final Integer MIN_NAME_LENGTH_DEFAULT = 3;
private static final String UNDERLINE_SYM = "_"; //$NON-NLS-1$
/**
* Instantiates a new instance of filter by variable name.
*/
public VariableNameInvalidCheck()
{
super();
}
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.VariableNameInvalidCheck_title)
.description(Messages.VariableNameInvalidCheck_description)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MINOR)
.issueType(IssueType.CODE_STYLE)
.extension(new StandardCheckExtension(454, getCheckId(), BslPlugin.PLUGIN_ID))
.module()
.checkedObjectType(VARIABLE, STATIC_FEATURE_ACCESS, DECLARE_STATEMENT)
.parameter(MIN_NAME_LENGTH_PARAM_NAME, Integer.class, MIN_NAME_LENGTH_DEFAULT.toString(),
Messages.VariableNameInvalidCheck_param_MIN_NAME_LENGTH_PARAM_title);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor)
{
int minLength = parameters.getInt(MIN_NAME_LENGTH_PARAM_NAME);
if (minLength <= 0)
{
minLength = MIN_NAME_LENGTH_DEFAULT;
}
if (object instanceof Variable)
{
checkVariable((Variable)object, minLength, resultAceptor);
}
else if (object instanceof DeclareStatement)
{
for (ExplicitVariable variable : ((DeclareStatement)object).getVariables())
{
if (monitor.isCanceled())
{
return;
}
checkVariable(variable, minLength, resultAceptor);
}
}
else if (object instanceof StaticFeatureAccess)
{
Variable variable = ((StaticFeatureAccess)object).getImplicitVariable();
if (variable == null || monitor.isCanceled())
{
return;
}
if (!isForStatementAccessVariable(variable))
{
checkVariable(variable, minLength, resultAceptor);
}
}
}
private void checkVariable(Variable variable, int minLength, ResultAcceptor resultAceptor)
{
String name = variable.getName();
int nameLength = name.length();
String msgTemplate = Messages.VariableNameInvalidCheck_variable_name_is_invalid;
String msg = null;
if (nameLength < minLength)
{
msg = MessageFormat.format(msgTemplate, name, MessageFormat
.format(Messages.VariableNameInvalidCheck_message_variable_length_is_less_than, minLength));
resultAceptor.addIssue(msg, variable, NAMED_ELEMENT__NAME);
}
if (name.startsWith(UNDERLINE_SYM))
{
msg = MessageFormat.format(msgTemplate, name,
Messages.VariableNameInvalidCheck_variable_name_starts_with_an_underline);
resultAceptor.addIssue(msg, variable, NAMED_ELEMENT__NAME);
}
else if (!Character.isUpperCase(name.charAt(0)))
{
msg = MessageFormat.format(msgTemplate, name,
Messages.VariableNameInvalidCheck_variable_name_must_start_with_a_capital_letter);
resultAceptor.addIssue(msg, variable, NAMED_ELEMENT__NAME);
}
}
private boolean isForStatementAccessVariable(Variable variable)
{
return EcoreUtil2.getContainerOfType(variable, ForStatement.class) != null;
}
}

View File

@ -457,3 +457,17 @@ UseNonRecommendedMethods_message = Using non-recommended method
UseNonRecommendedMethods_parameter = List of non-recommended methods
UseNonRecommendedMethods_title = Using non-recommended methods
VariableNameInvalidCheck_description=Variable name is invalid
VariableNameInvalidCheck_message_variable_length_is_less_than=variable length is less than {0}
VariableNameInvalidCheck_param_MIN_NAME_LENGTH_PARAM_title=Min. lenght of variable name
VariableNameInvalidCheck_title=Variable name is invalid
VariableNameInvalidCheck_variable_name_is_invalid=Variable name {0} is invalid: {1}
VariableNameInvalidCheck_variable_name_must_start_with_a_capital_letter=variable name must start with a capital letter
VariableNameInvalidCheck_variable_name_starts_with_an_underline=variable name starts with an underline

View File

@ -457,3 +457,17 @@ UseNonRecommendedMethods_message = Используется не рекомен
UseNonRecommendedMethods_parameter = Список дополнительных не рекомендуемых методов для проверки
UseNonRecommendedMethods_title = Использование не рекомендуемых методов
VariableNameInvalidCheck_description = Имя переменной введено некорректно
VariableNameInvalidCheck_message_variable_length_is_less_than = длина переменной меньше, чем {0}
VariableNameInvalidCheck_param_MIN_NAME_LENGTH_PARAM_title = Мин. длина переменной
VariableNameInvalidCheck_title = Имя переменной введено некорректно
VariableNameInvalidCheck_variable_name_is_invalid = Имя переменной {0} введено некорректно: {1}
VariableNameInvalidCheck_variable_name_must_start_with_a_capital_letter = имя переменной должно начинаться с заглавной буквы
VariableNameInvalidCheck_variable_name_starts_with_an_underline = имя переменной начинается с символа подчеркивания

View File

@ -0,0 +1,37 @@
Процедура ТестПодчеркивания()
Перем _ЯвнаяПеременнаяТестоваяПодчеркивание;
_НеявнаяПеременнаяПодчеркивание = 2;
КонецПроцедуры
Процедура ТестЗаглавнаяБуква()
Перем явнаяПеременнаяТестоваяНижнийРегистр;
неявнаяПеременнаяНижнийРегистр = 2;
КонецПроцедуры
Процедура ТестМинимальнаяДлина()
Перем ЯП;
НП = 2;
КонецПроцедуры
Процедура ТестКорректныеНаименования()
Перем ЯвнаяПеременнаяКорректноеНаименование;
НеявнаяПеременнаяКорректноеНаименование = 2;
КонецПроцедуры
Процедура ТестИтераторы()
МассивКонтрагентов = Новый Массив();
Для й = 0 По МассивКонтрагентов.ВГраница() Цикл
//Обработка массива
КонецЦикла;
Для Каждого Эл Из МассивКонтрагентов Цикл
//Обработка массива
КонецЦикла;
КонецПроцедуры
Процедура ТестИменаПараметровМетодов(Контрагенты)
КонецПроцедуры
Процедура ТестИменаПараметровМетодов2(_Контрагенты)
КонецПроцедуры

View File

@ -0,0 +1,55 @@
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.IExtraInfoKeys;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.VariableNameInvalidCheck;
/**
* The test for class {@link VariableNameInvalidCheck}.
*
* @author Vadim Goncharov
*
*/
public class VariableNameInvalidCheckTest
extends AbstractSingleModuleTestBase
{
public VariableNameInvalidCheckTest()
{
super(VariableNameInvalidCheck.class);
}
/**
* Test use invalid variable name.
*
* @throws Exception the exception
*/
@Test
public void testVariableName() throws Exception
{
updateModule(FOLDER_RESOURCE + "bsl-variable-name-invalid.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(7, markers.size());
List<String> benchmarkLines = Arrays.asList("2", "3", "7", "8", "12", "13", "36");
List<String> markersLines = new ArrayList<>();
for (Marker m : markers)
{
markersLines.add(m.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
assertEquals(true, markersLines.containsAll(benchmarkLines) && benchmarkLines.containsAll(markersLines));
}
}