1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2025-02-09 04:03:27 +02:00

Добавлена проверка кода инициализации (#1113)

#603 #535 #375
This commit is contained in:
Artem Iliukhin 2022-08-10 01:03:44 -06:00 committed by GitHub
parent ef99adbaa0
commit c0b072217d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 551 additions and 0 deletions

View File

@ -52,6 +52,7 @@
- Структура модуля. Добавлена проверка области событий.
- Отсутствует включение безопасного режима перед вызовом метода "Выполнить" или "Вычислить"
- Структура модуля. Добавлена проверка метода вне области.
- Структура модуля. Проверка что код инициализации расположен в области инициализации.
- Структура модуля. Область объявления переменных.

View File

@ -0,0 +1,34 @@
# The initialization section contains initialize code
The initialization section contains operators that initialize module variables or an object (form).
## Noncompliant Code Example
```bsl
SupportEmail = "v8@1c.ru";
Ctor();
...
```bsl
## Compliant Solution
```bsl
#Region Initialize
SupportEmail = "v8@1c.ru";
Ctor();
...
#EndRegion
```bsl
## See
- [Module structure](https://1c-dn.com/library/module_structure/)
- [Module structure](https://support.1ci.com/hc/en-us/articles/360011002360-Module-structure)

View File

@ -0,0 +1,32 @@
# Раздел инициализации содержит код инициализации
Раздел инициализации содержит операторы, инициализирующие переменные модуля или объект (форму).
## Неправильно
```bsl
АдресПоддержки = "v8@1c.ru";
ВыполнитьИнициализацию();
...
```
## Правильно
```bsl
#Область Инициализация
АдресПоддержки = "v8@1c.ru";
ВыполнитьИнициализацию();
...
#КонецОбласти
```
## См.
- [Структура модуля](https://its.1c.ru/db/v8std#content:455:hdoc)

View File

@ -291,6 +291,10 @@
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.BeginTransactionCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleStructureInitCodeInRegionCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleStructureVariablesInRegionCheck">

View File

@ -174,6 +174,12 @@ final class Messages
public static String ModuleStructureEventRegionsCheck_Title;
public static String ModuleStructureInitCodeInRegion_Description;
public static String ModuleStructureInitCodeInRegion_Issue__0;
public static String ModuleStructureInitCodeInRegion_Title;
public static String ModuleStructureMethodInRegionCheck_Description;
public static String ModuleStructureMethodInRegionCheck_Method_should_be_placed_in_one_of_the_standard_regions;

View File

@ -0,0 +1,120 @@
/*******************************************************************************
* 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.MODULE;
import java.text.MessageFormat;
import java.util.List;
import java.util.Optional;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.xtext.EcoreUtil2;
import com._1c.g5.v8.dt.bsl.model.EmptyStatement;
import com._1c.g5.v8.dt.bsl.model.Method;
import com._1c.g5.v8.dt.bsl.model.Module;
import com._1c.g5.v8.dt.bsl.model.ModuleType;
import com._1c.g5.v8.dt.bsl.model.RegionPreprocessor;
import com._1c.g5.v8.dt.bsl.model.Statement;
import com._1c.g5.v8.dt.core.platform.IV8ProjectManager;
import com._1c.g5.v8.dt.metadata.mdclass.ScriptVariant;
import com.e1c.g5.v8.dt.check.CheckComplexity;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.ModuleTopObjectNameFilterExtension;
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.e1c.v8codestyle.bsl.ModuleStructureSection;
import com.e1c.v8codestyle.check.StandardCheckExtension;
import com.e1c.v8codestyle.internal.bsl.BslPlugin;
import com.google.inject.Inject;
/**
* Checks that initialize code should be placed in the Initialize region
*
* @author Artem Iliukhin
*/
public class ModuleStructureInitCodeInRegionCheck
extends AbstractModuleStructureCheck
{
private static final String CHECK_ID = "module-structure-init-code-in-region"; //$NON-NLS-1$
private final IV8ProjectManager v8ProjectManager;
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Inject
public ModuleStructureInitCodeInRegionCheck(IV8ProjectManager v8ProjectManager)
{
this.v8ProjectManager = v8ProjectManager;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.ModuleStructureInitCodeInRegion_Title)
.description(Messages.ModuleStructureInitCodeInRegion_Description)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MINOR)
.issueType(IssueType.CODE_STYLE)
.extension(new ModuleTopObjectNameFilterExtension())
.extension(new StandardCheckExtension(getCheckId(), BslPlugin.PLUGIN_ID))
.extension(ModuleTypeFilter.excludeTypes(ModuleType.COMMON_MODULE, ModuleType.COMMAND_MODULE,
ModuleType.MANAGER_MODULE, ModuleType.SESSION_MODULE))
.module()
.checkedObjectType(MODULE);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor)
{
Module module = (Module)object;
ScriptVariant scriptVariant = v8ProjectManager.getProject(module).getScriptVariant();
String initialize = ModuleStructureSection.INITIALIZE.getName(scriptVariant);
List<Statement> statements = module.allStatements();
for (Statement statement : statements)
{
if (monitor.isCanceled())
{
return;
}
if (!(statement instanceof EmptyStatement))
{
addIssue(resultAceptor, initialize, statement);
}
}
}
private void addIssue(ResultAcceptor resultAceptor, String initialize, Statement statement)
{
if (EcoreUtil2.getContainerOfType(statement, Method.class) == null)
{
Optional<RegionPreprocessor> topRegion = getTopParentRegion(statement);
if (topRegion.isEmpty() || !initialize.equalsIgnoreCase(topRegion.get().getName()))
{
resultAceptor.addIssue(
MessageFormat.format(Messages.ModuleStructureInitCodeInRegion_Issue__0, initialize), statement);
}
}
}
}

View File

@ -239,6 +239,12 @@ ModuleStructureEventRegionsCheck_Only_event_methods__0=Only event methods can be
ModuleStructureEventRegionsCheck_Title=Checks the region of event handlers for the existence of methods related only to handlers
ModuleStructureInitCodeInRegion_Description=Initialize code should be placed in the Initialize region
ModuleStructureInitCodeInRegion_Issue__0=Initialize code should be placed in the {0} region
ModuleStructureInitCodeInRegion_Title=Initialize code is in the correct region
ModuleStructureMethodInRegionCheck_Description=Checks that the method is outside the standard region, and suggests placing the method in one of the standard regions for the current type of module
ModuleStructureMethodInRegionCheck_Method_should_be_placed_in_one_of_the_standard_regions=The method "{0}" should be placed in one of the standard regions: {1}

View File

@ -222,6 +222,12 @@ ModuleStructureMethodInRegionCheck_Description = Проверяет что ме
ModuleStructureMethodInRegionCheck_Method_should_be_placed_in_one_of_the_standard_regions = Метод "{0}" необходимо разместить в одной из верхнеуровневых областей: {1}
ModuleStructureInitCodeInRegion_Description=Код инициализации следует расположить в области инициализации
ModuleStructureInitCodeInRegion_Issue__0=Код инициализации следует расположить в области {0}
ModuleStructureInitCodeInRegion_Title=Код инициализации расположен не в правильной области
ModuleStructureVariablesInRegionCheck_Description=Объявление переменной должно быть помещено в область объявления переменной
ModuleStructureVariablesInRegionCheck_Issue__0=Объявление переменной должно быть помещено в область {0}

View File

@ -0,0 +1,85 @@
/*******************************************************************************
* 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 static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.core.runtime.Path;
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.g5.v8.dt.testing.check.SingleProjectReadOnlyCheckTestBase;
import com.e1c.v8codestyle.bsl.check.ModuleStructureInitCodeInRegionCheck;
/**
* Tests for {@link ModuleStructureInitCodeInRegionCheck} check.
*
* @author Artem Iliukhin
*/
public class ModuleStructureInitCodeInRegionCheckTest
extends SingleProjectReadOnlyCheckTestBase
{
private static final String CHECK_ID = "module-structure-init-code-in-region"; //$NON-NLS-1$
private static final String PROJECT_NAME = "ModuleStructureInitCodeInRegion";
private static final String CATALOG_MODULE_FILE_NAME = "/src/Catalogs/Catalog/ObjectModule.bsl";
private static final String CATALOG_WRONG_REGION_FILE_NAME = "/src/Catalogs/CatalogWrongRegion/ObjectModule.bsl";
private static final String CATALOG_OUT_OF_REGION_FILE_NAME = "/src/Catalogs/CatalogOutRegion/ObjectModule.bsl";
@Override
protected String getTestConfigurationName()
{
return PROJECT_NAME;
}
@Test
public void testInitializeInRegion() throws Exception
{
List<Marker> markers = getMarkers(CATALOG_MODULE_FILE_NAME);
assertTrue(markers.isEmpty());
}
@Test
public void testInWrongRegion() throws Exception
{
List<Marker> markers = getMarkers(CATALOG_WRONG_REGION_FILE_NAME);
assertEquals(1, markers.size());
assertEquals("20", markers.get(0).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
@Test
public void testOutOfRegion() throws Exception
{
List<Marker> markers = getMarkers(CATALOG_OUT_OF_REGION_FILE_NAME);
assertEquals(1, markers.size());
assertEquals("31", markers.get(0).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
private List<Marker> getMarkers(String moduleFileName)
{
String moduleId = Path.ROOT.append(getTestConfigurationName()).append(moduleFileName).toString();
List<Marker> markers = List.of(markerManager.getMarkers(getProject().getWorkspaceProject(), moduleId));
return markers.stream()
.filter(marker -> CHECK_ID.equals(getCheckIdFromMarker(marker, getProject())))
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ModuleStructureInitCodeInRegion</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
<nature>com._1c.g5.v8.dt.core.V8ConfigurationNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,2 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.19

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="c158963d-30e6-48be-8378-ba6a1b72caa6">
<producedTypes>
<objectType typeId="ce74853f-b0f5-4909-b1b7-f1feee6009e7" valueTypeId="2d3b190e-3195-4163-bd82-ef5bcccddc83"/>
<refType typeId="fbab96bb-595d-4451-bf9d-5668e7232ab2" valueTypeId="4ce269c2-18da-4bee-8898-3b312e7f3302"/>
<selectionType typeId="84afb3cd-43e6-40d1-a1a0-3c55908bc4bb" valueTypeId="cf089173-49d0-4b64-ab61-d48e5e45b44b"/>
<listType typeId="e3954219-2fe9-469a-9847-cb7211d80628" valueTypeId="ec80af51-2901-4cbe-b017-adc4203620e5"/>
<managerType typeId="982b375a-6d64-4d76-b9b9-604c0a080515" valueTypeId="fe351b3c-3992-481f-b1ff-81090f3fb659"/>
</producedTypes>
<name>Catalog</name>
<synonym>
<key>en</key>
<value>Catalog</value>
</synonym>
<useStandardCommands>true</useStandardCommands>
<inputByString>Catalog.Catalog.StandardAttribute.Code</inputByString>
<inputByString>Catalog.Catalog.StandardAttribute.Description</inputByString>
<fullTextSearchOnInputByString>DontUse</fullTextSearchOnInputByString>
<createOnInput>Use</createOnInput>
<dataLockControlMode>Managed</dataLockControlMode>
<fullTextSearch>Use</fullTextSearch>
<levelCount>2</levelCount>
<foldersOnTop>true</foldersOnTop>
<codeLength>9</codeLength>
<descriptionLength>25</descriptionLength>
<codeType>String</codeType>
<codeAllowedLength>Variable</codeAllowedLength>
<checkUnique>true</checkUnique>
<autonumbering>true</autonumbering>
<defaultPresentation>AsDescription</defaultPresentation>
<editType>InDialog</editType>
<choiceMode>BothWays</choiceMode>
</mdclass:Catalog>

View File

@ -0,0 +1,31 @@
#Region Variables
Var a;
#EndRegion
#Region Public
// Enter code here.
#EndRegion
#Region EventHandlers
// Enter code here.
#EndRegion
#Region Internal
// Enter code here.
Procedure Complient()
// enter code here
EndProcedure
#EndRegion
#Region Private
// Enter code here.
#EndRegion
#Region Initialize
a = True;
Complient();
#EndRegion

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="5cfe5600-9418-4ffa-a871-dd7322a7b2c7">
<producedTypes>
<objectType typeId="25685e6f-6f1d-41ea-837c-732f6ecd7bb6" valueTypeId="4e1502a0-0277-4f9d-9af6-2695ae7fb899"/>
<refType typeId="08cda41e-8c19-4c10-8f54-ee4feb7a3a28" valueTypeId="d910fc98-5742-4c38-98dd-c1d2a8a88df4"/>
<selectionType typeId="037c024e-9f12-4999-b198-05271151b096" valueTypeId="af9a5eea-007e-41a4-b873-f71025758954"/>
<listType typeId="a814dc5e-d338-4a59-94e6-f0b87693f402" valueTypeId="25b9f5dd-4a6a-4e20-8399-4e128c4a5a56"/>
<managerType typeId="1dc1cb72-fa97-4317-879b-75fa4d0b8225" valueTypeId="b6bff1de-71b5-4ad7-8f58-d37fd1acfa44"/>
</producedTypes>
<name>CatalogOutRegion</name>
<synonym>
<key>en</key>
<value>Catalog out region</value>
</synonym>
<useStandardCommands>true</useStandardCommands>
<inputByString>Catalog.CatalogOutRegion.StandardAttribute.Code</inputByString>
<inputByString>Catalog.CatalogOutRegion.StandardAttribute.Description</inputByString>
<fullTextSearchOnInputByString>DontUse</fullTextSearchOnInputByString>
<createOnInput>Use</createOnInput>
<dataLockControlMode>Managed</dataLockControlMode>
<fullTextSearch>Use</fullTextSearch>
<levelCount>2</levelCount>
<foldersOnTop>true</foldersOnTop>
<codeLength>9</codeLength>
<descriptionLength>25</descriptionLength>
<codeType>String</codeType>
<codeAllowedLength>Variable</codeAllowedLength>
<checkUnique>true</checkUnique>
<autonumbering>true</autonumbering>
<defaultPresentation>AsDescription</defaultPresentation>
<editType>InDialog</editType>
<choiceMode>BothWays</choiceMode>
</mdclass:Catalog>

View File

@ -0,0 +1,32 @@
#Region Variables
Var a;
#EndRegion
#Region Public
// Enter code here.
#EndRegion
#Region EventHandlers
// Enter code here.
#EndRegion
#Region Internal
// Enter code here.
Procedure Complient()
// enter code here
EndProcedure
#EndRegion
#Region Private
// Enter code here.
#EndRegion
#Region Initialize
Complient();
#EndRegion
a = True;

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Catalog xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="9bfba4eb-5998-493b-af09-a2d8284735de">
<producedTypes>
<objectType typeId="822478cb-00f5-4832-b856-821d3d42e4b0" valueTypeId="7b3f917f-0f80-46b4-b23f-c8608b4e01cf"/>
<refType typeId="6402f581-8208-4f6e-b797-1f988980fe2b" valueTypeId="1a55e94b-e23d-4c6a-bf31-0df9b40a4293"/>
<selectionType typeId="7eca2d11-596f-4cb7-af94-ac6ee12d6535" valueTypeId="6f8c2b39-ef9f-40ed-b183-f90660f91898"/>
<listType typeId="55de14c3-2a05-432d-9a38-6ba9259b2ae6" valueTypeId="62c567d8-09af-4175-a3cc-e6d67b58aac7"/>
<managerType typeId="08b6588a-640f-45a0-98ce-123906ace15a" valueTypeId="5ea8db67-bbc8-4ce3-a5a8-b7289f1cfa82"/>
</producedTypes>
<name>CatalogWrongRegion</name>
<synonym>
<key>en</key>
<value>Catalog wrong region</value>
</synonym>
<useStandardCommands>true</useStandardCommands>
<inputByString>Catalog.CatalogWrongRegion.StandardAttribute.Code</inputByString>
<inputByString>Catalog.CatalogWrongRegion.StandardAttribute.Description</inputByString>
<fullTextSearchOnInputByString>DontUse</fullTextSearchOnInputByString>
<createOnInput>Use</createOnInput>
<dataLockControlMode>Managed</dataLockControlMode>
<fullTextSearch>Use</fullTextSearch>
<levelCount>2</levelCount>
<foldersOnTop>true</foldersOnTop>
<codeLength>9</codeLength>
<descriptionLength>25</descriptionLength>
<codeType>String</codeType>
<codeAllowedLength>Variable</codeAllowedLength>
<checkUnique>true</checkUnique>
<autonumbering>true</autonumbering>
<defaultPresentation>AsDescription</defaultPresentation>
<editType>InDialog</editType>
<choiceMode>BothWays</choiceMode>
</mdclass:Catalog>

View File

@ -0,0 +1,25 @@
#Region Variables
Var a;
#EndRegion
#Region Public
// Enter code here.
#EndRegion
#Region EventHandlers
// Enter code here.
#EndRegion
#Region Internal
// Enter code here.
#EndRegion
#Region Private
// Enter code here.
a = True;
#EndRegion
#Region Initialize
#EndRegion

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<cmi:CommandInterface xmlns:cmi="http://g5.1c.ru/v8/dt/cmi"/>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Configuration xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="311188e3-df8f-4ca2-90d3-9242fe3d46a2">
<name>ModuleStructureInitCodeInRegion</name>
<synonym>
<key>en</key>
<value>Module structure init code in region</value>
</synonym>
<containedObjects classId="9cd510cd-abfc-11d4-9434-004095e12fc7" objectId="bbdc6009-392b-456d-bdfd-f3a9b290d6d0"/>
<containedObjects classId="9fcd25a0-4822-11d4-9414-008048da11f9" objectId="ba793a66-07c3-4b59-81be-77df208d84c7"/>
<containedObjects classId="e3687481-0a87-462c-a166-9f34594f9bba" objectId="37102548-dce3-4bfc-b0d9-e6f54c797c10"/>
<containedObjects classId="9de14907-ec23-4a07-96f0-85521cb6b53b" objectId="9776cd58-fb13-48d1-9e13-8993104632dc"/>
<containedObjects classId="51f2d5d8-ea4d-4064-8892-82951750031e" objectId="8c5c81eb-0b7c-468f-bba8-220d8f3fb2d1"/>
<containedObjects classId="e68182ea-4237-4383-967f-90c1e3370bc7" objectId="2395e1ef-7f79-46af-a1c3-5ba53761fc9b"/>
<containedObjects classId="fb282519-d103-4dd3-bc12-cb271d631dfc" objectId="fcb9ec04-5fcd-476a-9f64-3ec84492ae64"/>
<configurationExtensionCompatibilityMode>8.3.19</configurationExtensionCompatibilityMode>
<defaultRunMode>ManagedApplication</defaultRunMode>
<usePurposes>PersonalComputer</usePurposes>
<usedMobileApplicationFunctionalities>
<functionality>
<use>true</use>
</functionality>
<functionality>
<functionality>OSBackup</functionality>
<use>true</use>
</functionality>
</usedMobileApplicationFunctionalities>
<defaultLanguage>Language.English</defaultLanguage>
<dataLockControlMode>Managed</dataLockControlMode>
<objectAutonumerationMode>NotAutoFree</objectAutonumerationMode>
<modalityUseMode>DontUse</modalityUseMode>
<synchronousPlatformExtensionAndAddInCallUseMode>DontUse</synchronousPlatformExtensionAndAddInCallUseMode>
<compatibilityMode>8.3.19</compatibilityMode>
<languages uuid="67dd2353-e5cb-4da9-984e-5d6658bcd615">
<name>English</name>
<synonym>
<key>en</key>
<value>English</value>
</synonym>
<languageCode>en</languageCode>
</languages>
<catalogs>Catalog.Catalog</catalogs>
<catalogs>Catalog.CatalogOutRegion</catalogs>
<catalogs>Catalog.CatalogWrongRegion</catalogs>
</mdclass:Configuration>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<cmi:CommandInterface xmlns:cmi="http://g5.1c.ru/v8/dt/cmi"/>