mirror of
https://github.com/1C-Company/v8-code-style.git
synced 2024-12-01 10:41:05 +02:00
Стандарт 492: Использован обработчик событий, подключаемый из кода и не
содержащий префикса "Подключаемый_". #392
This commit is contained in:
parent
87afe0ee2c
commit
1b056b185b
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
- Добавление типизированного значения в не типизированную коллекцию
|
- Добавление типизированного значения в не типизированную коллекцию
|
||||||
- Устаревшая процедура (функция) расположена вне области "УстаревшиеПроцедурыИФункции"
|
- Устаревшая процедура (функция) расположена вне области "УстаревшиеПроцедурыИФункции"
|
||||||
|
- Использован обработчик событий, подключаемый из кода и не содержащий префикса "Подключаемый_"
|
||||||
|
|
||||||
#### Запросы
|
#### Запросы
|
||||||
|
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
# Attachable event handler name
|
||||||
|
|
||||||
|
Programmatically added event handler name should match pattern: **Attachable_** prefix
|
||||||
|
|
||||||
|
## Noncompliant Code Example
|
||||||
|
|
||||||
|
```bsl
|
||||||
|
// Parameters:
|
||||||
|
// Item - FormField
|
||||||
|
Procedure Incorrect(Item)
|
||||||
|
|
||||||
|
Item.SetAction("OnChange", "IncorrectOnChange");
|
||||||
|
|
||||||
|
EndProcedure
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compliant Solution
|
||||||
|
|
||||||
|
```bsl
|
||||||
|
// Parameters:
|
||||||
|
// Item - FormField
|
||||||
|
Procedure Correct(Item)
|
||||||
|
|
||||||
|
Item.SetAction("OnChange", "Attachable_CorrectOnChange");
|
||||||
|
|
||||||
|
EndProcedure
|
||||||
|
```
|
||||||
|
|
||||||
|
## See
|
||||||
|
|
||||||
|
- [Form module event handlers attached in code](https://kb.1ci.com/1C_Enterprise_Platform/Guides/Developer_Guides/1C_Enterprise_Development_Standards/Code_conventions/Using_1C_Enterprise_language_structures/Form_module_event_handlers_attached_in_code/)
|
@ -0,0 +1,31 @@
|
|||||||
|
# Имя подключаемого обработчка события
|
||||||
|
|
||||||
|
Имя программно добавленного обработчика события должно соответствать шаблону: префикс **Подключаемый_**
|
||||||
|
|
||||||
|
## Неправильно
|
||||||
|
|
||||||
|
```bsl
|
||||||
|
// Параметры:
|
||||||
|
// Элемент - FormField
|
||||||
|
Процедура Неправильно(Элемент)
|
||||||
|
|
||||||
|
Элемент.SetAction("ПриИзменении", "НеправильноПриИзменении");
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
```
|
||||||
|
|
||||||
|
## Правильно
|
||||||
|
|
||||||
|
```bsl
|
||||||
|
// Параметры:
|
||||||
|
// Элемент - FormField
|
||||||
|
Процедура Правильно(Элемент)
|
||||||
|
|
||||||
|
Элемент.SetAction("ПриИзменении", "Подключаемый_ПравильноПриИзменении");
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
```
|
||||||
|
|
||||||
|
## См.
|
||||||
|
|
||||||
|
- [Обработчики событий модуля формы, подключаемые из кода](https://its.1c.ru/db/v8std#content:492:hdoc)
|
@ -299,6 +299,10 @@
|
|||||||
category="com.e1c.v8codestyle.bsl"
|
category="com.e1c.v8codestyle.bsl"
|
||||||
class="com.e1c.v8codestyle.bsl.check.BeginTransactionCheck">
|
class="com.e1c.v8codestyle.bsl.check.BeginTransactionCheck">
|
||||||
</check>
|
</check>
|
||||||
|
<check
|
||||||
|
category="com.e1c.v8codestyle.bsl"
|
||||||
|
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.AttachableEventHandlerNameCheck">
|
||||||
|
</check>
|
||||||
<check
|
<check
|
||||||
category="com.e1c.v8codestyle.bsl"
|
category="com.e1c.v8codestyle.bsl"
|
||||||
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleStructureInitCodeInRegionCheck">
|
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleStructureInitCodeInRegionCheck">
|
||||||
|
@ -0,0 +1,151 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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.INVOCATION;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.xtext.EcoreUtil2;
|
||||||
|
|
||||||
|
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.FeatureAccess;
|
||||||
|
import com._1c.g5.v8.dt.bsl.model.Invocation;
|
||||||
|
import com._1c.g5.v8.dt.bsl.model.ModuleType;
|
||||||
|
import com._1c.g5.v8.dt.bsl.model.StringLiteral;
|
||||||
|
import com._1c.g5.v8.dt.bsl.resource.TypesComputer;
|
||||||
|
import com._1c.g5.v8.dt.common.StringUtils;
|
||||||
|
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._1c.g5.v8.dt.platform.IEObjectTypeNames;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The check finds invocation {@code object.SetAction("Event", "Attachable_HandlerName");} and validate that handler
|
||||||
|
* name matches pattern for attachable procedures.
|
||||||
|
* Form modules should be excluded because local methods must be found by direct reference.
|
||||||
|
*
|
||||||
|
* @author Dmitriy Marmyshev
|
||||||
|
*/
|
||||||
|
public class AttachableEventHandlerNameCheck
|
||||||
|
extends BasicCheck
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final String CHECK_ID = "module-attachable-event-handler-name"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static final String METHOD_NAME = "SetAction"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static final String METHOD_NAME_RU = "УстановитьДействие"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static final String DEFAULT_PARAM_ACTION_PATTERN = "^(?U)(Подключаемый|Attachable)_.*$"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static final String PARAM_ACTION_PATTERN = "actionNamePattern"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
private static final Set<String> SET_ACTION_TYPES = Set.of(
|
||||||
|
IEObjectTypeNames.CLIENT_APPLICATION_FORM,
|
||||||
|
IEObjectTypeNames.MANAGED_FORM,
|
||||||
|
IEObjectTypeNames.FORM_FIELD,
|
||||||
|
IEObjectTypeNames.FORM_GROUP,
|
||||||
|
IEObjectTypeNames.FORM_TABLE,
|
||||||
|
IEObjectTypeNames.FORM_DECORATION);
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
private final TypesComputer typesComputer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new attachable event handler name check.
|
||||||
|
*
|
||||||
|
* @param typesComputer the types computer, cannot be {@code null}.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
public AttachableEventHandlerNameCheck(TypesComputer typesComputer)
|
||||||
|
{
|
||||||
|
this.typesComputer = typesComputer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCheckId()
|
||||||
|
{
|
||||||
|
return CHECK_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureCheck(CheckConfigurer builder)
|
||||||
|
{
|
||||||
|
builder.title(Messages.AttachableEventHandlerNameCheck_Title)
|
||||||
|
.description(Messages.AttachableEventHandlerNameCheck_Description)
|
||||||
|
.complexity(CheckComplexity.NORMAL)
|
||||||
|
.severity(IssueSeverity.MINOR)
|
||||||
|
.issueType(IssueType.CODE_STYLE)
|
||||||
|
.extension(new StandardCheckExtension(492, getCheckId(), BslPlugin.PLUGIN_ID))
|
||||||
|
.extension(ModuleTypeFilter.excludeTypes(ModuleType.FORM_MODULE))
|
||||||
|
.module()
|
||||||
|
.checkedObjectType(INVOCATION)
|
||||||
|
.parameter(PARAM_ACTION_PATTERN, String.class, DEFAULT_PARAM_ACTION_PATTERN,
|
||||||
|
Messages.AttachableEventHandlerNameCheck_Event_handler_name_pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
|
||||||
|
IProgressMonitor monitor)
|
||||||
|
{
|
||||||
|
Invocation inv = (Invocation)object;
|
||||||
|
FeatureAccess method = inv.getMethodAccess();
|
||||||
|
String methodName = method.getName();
|
||||||
|
String actionPattern = parameters.getString(PARAM_ACTION_PATTERN);
|
||||||
|
if (!(method instanceof DynamicFeatureAccess) || StringUtils.isEmpty(actionPattern)
|
||||||
|
|| inv.getParams().size() != 2 || !(inv.getParams().get(1) instanceof StringLiteral)
|
||||||
|
|| !(METHOD_NAME_RU.equalsIgnoreCase(methodName) || METHOD_NAME.equalsIgnoreCase(methodName)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression parameter = inv.getParams().get(1);
|
||||||
|
String content = getStringContent(parameter);
|
||||||
|
if (content != null && !content.matches(actionPattern)
|
||||||
|
&& isExpectedTypes(((DynamicFeatureAccess)method).getSource()))
|
||||||
|
{
|
||||||
|
String message = MessageFormat.format(Messages.AttachableEventHandlerNameCheck_Message, methodName);
|
||||||
|
resultAceptor.addIssue(message, parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isExpectedTypes(Expression object)
|
||||||
|
{
|
||||||
|
Environmental env = EcoreUtil2.getContainerOfType(object, Environmental.class);
|
||||||
|
List<TypeItem> types = typesComputer.computeTypes(object, env.environments());
|
||||||
|
return types.stream().map(McoreUtil::getTypeName).filter(Objects::nonNull).anyMatch(SET_ACTION_TYPES::contains);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringContent(Expression parameter)
|
||||||
|
{
|
||||||
|
// TODO #1187 get string from content computer in future, for now hard-coded StringLiteral
|
||||||
|
StringLiteral literal = (StringLiteral)parameter;
|
||||||
|
return String.join(StringUtils.EMPTY, literal.lines(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -38,6 +38,14 @@ final class Messages
|
|||||||
public static String AccessibilityAtClientInObjectModuleCheck_Methods_should_be_AtClient;
|
public static String AccessibilityAtClientInObjectModuleCheck_Methods_should_be_AtClient;
|
||||||
|
|
||||||
public static String AccessibilityAtClientInObjectModuleCheck_title;
|
public static String AccessibilityAtClientInObjectModuleCheck_title;
|
||||||
|
public static String AttachableEventHandlerNameCheck_Description;
|
||||||
|
|
||||||
|
public static String AttachableEventHandlerNameCheck_Event_handler_name_pattern;
|
||||||
|
|
||||||
|
public static String AttachableEventHandlerNameCheck_Message;
|
||||||
|
|
||||||
|
public static String AttachableEventHandlerNameCheck_Title;
|
||||||
|
|
||||||
public static String CanonicalPragmaCheck_description;
|
public static String CanonicalPragmaCheck_description;
|
||||||
public static String CanonicalPragmaCheck_Pragma_0_is_not_written_canonically_correct_spelling_is_1;
|
public static String CanonicalPragmaCheck_Pragma_0_is_not_written_canonically_correct_spelling_is_1;
|
||||||
public static String CanonicalPragmaCheck_title;
|
public static String CanonicalPragmaCheck_title;
|
||||||
|
@ -28,6 +28,14 @@ AccessibilityAtClientInObjectModuleCheck_description = Method or variable access
|
|||||||
|
|
||||||
AccessibilityAtClientInObjectModuleCheck_title = Method or variable accessible AtClient
|
AccessibilityAtClientInObjectModuleCheck_title = Method or variable accessible AtClient
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Description = Programmatically added event handler name should match pattern
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Event_handler_name_pattern = Event handler name pattern
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Message = Programmatically added event handler name "{0}" should match pattern
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Title = Attachable event handler name
|
||||||
|
|
||||||
CanonicalPragmaCheck_Pragma_0_is_not_written_canonically_correct_spelling_is_1 = Annotation {0} is not written canonically, correct spelling is {1}
|
CanonicalPragmaCheck_Pragma_0_is_not_written_canonically_correct_spelling_is_1 = Annotation {0} is not written canonically, correct spelling is {1}
|
||||||
|
|
||||||
CanonicalPragmaCheck_description = Check pragma is written canonically
|
CanonicalPragmaCheck_description = Check pragma is written canonically
|
||||||
|
@ -28,6 +28,14 @@ AccessibilityAtClientInObjectModuleCheck_description = Метод или пер
|
|||||||
|
|
||||||
AccessibilityAtClientInObjectModuleCheck_title = Метод или переменная доступны НаКлиенте
|
AccessibilityAtClientInObjectModuleCheck_title = Метод или переменная доступны НаКлиенте
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Description = Имя программно добавленного обработчика события должно соответствать шаблону
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Event_handler_name_pattern = Шаблон имени обработчика события
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Message = Программно добавленное имя обработчика события "{0}" должно соответствать шаблону
|
||||||
|
|
||||||
|
AttachableEventHandlerNameCheck_Title = Имя подключаемого обработчка события
|
||||||
|
|
||||||
CanonicalPragmaCheck_Pragma_0_is_not_written_canonically_correct_spelling_is_1 = Аннотация {0} написана не канонически, правильное написание {1}
|
CanonicalPragmaCheck_Pragma_0_is_not_written_canonically_correct_spelling_is_1 = Аннотация {0} написана не канонически, правильное написание {1}
|
||||||
|
|
||||||
CanonicalPragmaCheck_description = Проверяет что аннотация метода написана канонически
|
CanonicalPragmaCheck_description = Проверяет что аннотация метода написана канонически
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
// Parameters:
|
||||||
|
// Item - FormField
|
||||||
|
Procedure Incorrect(Item)
|
||||||
|
|
||||||
|
Item.SetAction("OnChange", "CorrectOnChange");
|
||||||
|
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
|
||||||
|
// Parameters:
|
||||||
|
// Item - FormField
|
||||||
|
Procedure Correct(Item)
|
||||||
|
|
||||||
|
Item.SetAction("OnChange", "Attachable_CorrectOnChange");
|
||||||
|
|
||||||
|
EndProcedure
|
@ -0,0 +1,54 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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.IExtraInfoKeys;
|
||||||
|
import com._1c.g5.v8.dt.validation.marker.Marker;
|
||||||
|
import com.e1c.v8codestyle.bsl.check.AttachableEventHandlerNameCheck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link AttachableEventHandlerNameCheck} check.
|
||||||
|
*
|
||||||
|
* @author Dmitriy Marmyshev
|
||||||
|
*/
|
||||||
|
public class AttachableEventHandlerNameCheckTest
|
||||||
|
extends AbstractSingleModuleTestBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public AttachableEventHandlerNameCheckTest()
|
||||||
|
{
|
||||||
|
super(AttachableEventHandlerNameCheck.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test attachable event handler name.
|
||||||
|
*
|
||||||
|
* @throws Exception the exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAttachableEventHandlerName() throws Exception
|
||||||
|
{
|
||||||
|
updateModule(FOLDER_RESOURCE + "module-attachable-event-handler-name.bsl");
|
||||||
|
|
||||||
|
List<Marker> markers = getModuleMarkers();
|
||||||
|
assertEquals(1, markers.size());
|
||||||
|
Marker marker = markers.get(0);
|
||||||
|
assertEquals("6", marker.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user