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

#396 Вызов "Заблокировать()" находится вне попытки (#920)

This commit is contained in:
Artem Iliukhin 2022-02-12 13:16:32 +03:00 committed by GitHub
parent f14643cd97
commit e12607380b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 306 additions and 1 deletions

View File

@ -48,6 +48,7 @@
13. Определение типа документирующего комментария
- Исправлен идентификатор проверки тип в строгой типизации: `doc-comment-field-type` -> `doc-comment-field-type-strict`
- Ограничения на использование экспортных процедур и функций в модулях команд и форм
- Вызов "Заблокировать()" находится вне попытки
#### Запросы

View File

@ -0,0 +1,40 @@
# The "Lock()" call is out of the try block
The rule checks for initialization of the data lock. If the
creation of a lock is found, the call of the "Lock()" method is checked,
and the call must be in a try block.
## Noncompliant Code Example
```bsl
DataLock = new DataLock;
DataLockItem = DataLock.Add("Document.Test");
DataLockItem.Mode = DataLockMode.Exclusive;
DataLock.Lock();
```
## Compliant Solution
```bsl
BeginTransaction();
Try
DataLock = new DataLock;
DataLockItem = DataLock.Add("Document.Test");
DataLockItem.Mode = DataLockMode.Exclusive;
DataLock.Lock();
CommitTransaction();
Except
RollbackTransaction();
Raise;
EndTry;
```
## See
- [Catching exceptions in code](https://support.1ci.com/hc/en-us/articles/360011002440-Catching-exceptions-in-code)
- [Transactions: rules of use](https://support.1ci.com/hc/en-us/articles/360011121239-Transactions-rules-of-use)

View File

@ -0,0 +1,41 @@
# Вызов "Заблокировать()" находится вне попытки
Правило проверяет наличие инициализации блокировки данных. В случае если
найдено создание блокировки, проверяется вызов метода "Заблокировать()",
при этом вызов должен быть в попытке.
## Неправильно
```bsl
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("Документ.ПриходнаяНакладная");
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();
```
## Правильно
```bsl
НачатьТранзакцию();
Попытка
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("Документ.ПриходнаяНакладная");
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();
// чтение или запись данных
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
```
## См.
- [Перехват исключений в коде](https://its.1c.ru/db/v8std#content:499:hdoc:3.6)
- [Транзакции: правила использования](https://its.1c.ru/db/v8std#content:783:hdoc:1.3)

View File

@ -235,8 +235,12 @@
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.ExportMethodInCommandFormModuleCheck">
</check>
</extension>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.LockOutOfTryCheck">
</check>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<initializer

View File

@ -0,0 +1,117 @@
/*******************************************************************************
* Copyright (C) 2022, 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
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.DYNAMIC_FEATURE_ACCESS;
import java.util.List;
import java.util.Objects;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import com._1c.g5.v8.dt.bsl.model.DynamicFeatureAccess;
import com._1c.g5.v8.dt.bsl.model.Expression;
import com._1c.g5.v8.dt.bsl.model.TryExceptStatement;
import com._1c.g5.v8.dt.bsl.model.util.BslUtil;
import com._1c.g5.v8.dt.bsl.resource.TypesComputer;
import com._1c.g5.v8.dt.mcore.Environmental;
import com._1c.g5.v8.dt.mcore.TypeItem;
import com._1c.g5.v8.dt.mcore.util.McoreUtil;
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;
import com.google.inject.Inject;
/**
* Checks for initialization of the data lock. If the creation of a lock is found, the call of the Lock() method is
* checked, and the call must be in a try.
*
* @author Artem Iliukhin
*/
public final class LockOutOfTryCheck
extends BasicCheck
{
private static final String CHECK_ID = "lock-out-of-try"; //$NON-NLS-1$
private static final String NAME_DATA_LOCK = "DataLock"; //$NON-NLS-1$
private static final String NAME_LOCK = "Lock"; //$NON-NLS-1$
private static final String NAME_LOCK_RU = "Заблокировать"; //$NON-NLS-1$
private final TypesComputer typesComputer;
@Inject
public LockOutOfTryCheck()
{
super();
IResourceServiceProvider rsp =
IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(URI.createURI("*.bsl")); //$NON-NLS-1$
this.typesComputer = rsp.get(TypesComputer.class);
}
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.LockOutOfTry_Lock_out_of_try)
.description(Messages.LockOutOfTry_Checks_for_init_of_the_data_lock)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MINOR)
.issueType(IssueType.WARNING)
.extension(new StandardCheckExtension(getCheckId(), BslPlugin.PLUGIN_ID))
.module()
.checkedObjectType(DYNAMIC_FEATURE_ACCESS);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor)
{
DynamicFeatureAccess dynamicFeatureAccess = (DynamicFeatureAccess)object;
String name = dynamicFeatureAccess.getName();
if (BslUtil.getInvocation(dynamicFeatureAccess) == null
|| !NAME_LOCK.equalsIgnoreCase(name) && !NAME_LOCK_RU.equalsIgnoreCase(name))
{
return;
}
Expression source = dynamicFeatureAccess.getSource();
Environmental env = EcoreUtil2.getContainerOfType(source, Environmental.class);
if (Objects.isNull(env))
{
return;
}
List<TypeItem> types = typesComputer.computeTypes(source, env.environments());
for (TypeItem type : types)
{
if (NAME_DATA_LOCK.equals(McoreUtil.getTypeName(type))
&& Objects.isNull(EcoreUtil2.getContainerOfType(source, TryExceptStatement.class)))
{
resultAceptor.addIssue(Messages.LockOutOfTry_Method_lock_out_of_try, object);
}
}
}
}

View File

@ -205,6 +205,14 @@ final class Messages
public static String ModuleUndefinedFunction_msg;
public static String ModuleUndefinedMethod_msg;
public static String LockOutOfTry_BeginTransaction_method_must_by_outside_try_block;
public static String LockOutOfTry_Checks_for_init_of_the_data_lock;
public static String LockOutOfTry_Lock_out_of_try;
public static String LockOutOfTry_Method_lock_out_of_try;
static
{
// initialize resource bundle

View File

@ -104,6 +104,12 @@ IsInRoleCheck_Use_AccessRight_instead_IsInRole=Use the AccessRight() function in
IsInRoleCheck_Using_IsInRole=Using "IsInRole" method
LockOutOfTry_Checks_for_init_of_the_data_lock=Checks for initialization of the data lock. If the creation of a lock is found, the call of the Lock() method is checked, and the call must be in a try.
LockOutOfTry_Lock_out_of_try=Lock out of Try
LockOutOfTry_Method_lock_out_of_try=Method Lock() out of try block
MethodTooManyPramsCheck_Max_parameters = Max parameters
MethodTooManyPramsCheck_Max_parameters_with_default_value = Max parameters with default value

View File

@ -104,6 +104,12 @@ IsInRoleCheck_Using_IsInRole = Использован не рекомендов
IsInRoleCheck_Use_AccessRight_instead_IsInRole = Используйте функцию "ПравоДоступа()" вместо "РольДоступна()"
LockOutOfTry_Checks_for_init_of_the_data_lock=Правило проверяет наличие инициализации блокировки данных. В случае если найдено создание блокировки, проверяется вызов метода "Заблокировать()", при этом вызов должен быть в попытке.
LockOutOfTry_Lock_out_of_try=Метод Заблокировать() вне блока Попытка-Исключение
LockOutOfTry_Method_lock_out_of_try=Метод Заблокировать() вне блока Попытка-Исключение
MethodTooManyPramsCheck_Max_parameters = Максимум параметров
MethodTooManyPramsCheck_Max_parameters_with_default_value = Максимум параметров со значением по умолчанию

View File

@ -0,0 +1,8 @@
Процедура Тест()
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("Документ.ПриходнаяНакладная");
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();
КонецПроцедуры

View File

@ -0,0 +1,8 @@
Процедура Тест()
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = Блокировка.Добавить("Документ.ПриходнаяНакладная");
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
КонецПроцедуры

View File

@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (C) 2022, 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
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.LockOutOfTryCheck;
/**
* Tests for {@link LockOutOfTryCheck} check.
*
* @author Artem Iliukhin
*/
public class LockOutOfTryCheckTest
extends AbstractSingleModuleTestBase
{
private static final String LOCK_OUT_OF_TRY = "Method Lock() out of try block";
/**
* Test {@link LockOutOfTryCheck}.
*
* @param checkClass
*/
public LockOutOfTryCheckTest()
{
super(LockOutOfTryCheck.class);
}
@Test
public void testLockOutOfTry() throws Exception
{
updateModule(FOLDER_RESOURCE + "lock-out-of-try.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals(LOCK_OUT_OF_TRY, marker.getMessage());
}
@Test
public void testLockOutOfTry2() throws Exception
{
updateModule(FOLDER_RESOURCE + "lock-out-of-try2.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals(LOCK_OUT_OF_TRY, marker.getMessage());
}
}