1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2025-04-19 06:42:39 +02:00

Merge branch 'master' into edt-2023-3

This commit is contained in:
Dmitriy Marmyshev 2023-12-22 20:57:38 -08:00
commit de3f57d79a
19 changed files with 632 additions and 328 deletions

View File

@ -18,6 +18,9 @@
#### Код модулей
- Проверка на уникальность имени поля в doc-comment-field-name #1392
- Проверка модификации ключей структуры вне функции-конструктора #1054
#### Запросы

View File

@ -0,0 +1,68 @@
# Модификация ключа структуры вне функции-конструктора
Если Структура создана функцией-конструктором, то изменение состава ключей структуры методами
`Структура.Вставить("Ключ", ...); Структура.Удалить("Ключ"); Структура.Очистить();`
может приводить к ошибкам из-за неопределенности состава данных.
## Неправильно
Неправильно удалять все ключи структуры, удалять ключ или заменять ключ внешней структуры.
```bsl
// @strict-types
Процедура Неправильно1() Экспорт
ТестоваяСтруктура = Конструктор();
ТестоваяСтруктура.Очистить();
ТестоваяСтруктура.Вставить("Ключ1", 10);
ТестоваяСтруктура.Удалить("Ключ2");
КонецПроцедуры
// Возвращаемое значение:
// Структура:
// * Ключ1 - Булево -
// * Ключ2 - Число -
Функция Конструктор() Экспорт
ТестоваяСтруктура = новый Структура("Ключ1, Ключ2", Истина, 10);
ТестоваяСтруктура.Вставить("Ключ2", 20);
Возврат ТестоваяСтруктура;
КонецФункции
```
## Правильно
Обращаться к существующему ключу необходимо напрямую и устанавливать новое значение.
Вместо удаления ключа необходимо устанавливать значение, которое представляет пустое или начальное значение.
```bsl
// @strict-types
Процедура Правильно1() Экспорт
ТестоваяСтруктура = Конструктор();
ТестоваяСтруктура.Ключ1 = false;
ТестоваяСтруктура.Ключ2 = -1;
КонецПроцедуры
// Возвращаемое значение:
// Структура:
// * Ключ1 - Булево -
// * Ключ2 - Число -
Функция Конструктор() Экспорт
ТестоваяСтруктура = новый Структура("Ключ1, Ключ2", Истина, 10);
ТестоваяСтруктура.Вставить("Ключ2", 20);
Возврат ТестоваяСтруктура;
КонецФункции
```
## См.

View File

@ -0,0 +1,69 @@
# Structure key modification outside constructor function
If Structure was created by constructor function then changing the composition of the structure keys using methods
`Structure.Insert("Key", ...); Structure.Delete("Key"); Structure.Clear();`
can lead to errors due to the uncertainty of data composition.
## Noncompliant Code Example
Should not clear all structure keys, delete key or replace key of external structure.
```bsl
// @strict-types
Procedure Incorrect1() Export
TestStucture = Constructor();
TestStucture.Clear();
TestStucture.Insert("Key1", 10);
TestStucture.Delete("Key2");
EndProcedure
// Returns:
// Structure:
// * Key1 - Boolean -
// * Key2 - Number -
Function Constructor() Export
TestStucture = new Structure("Key1, Key2", true, 10);
TestStucture.Insert("Key2", 20);
Return TestStucture;
EndFunction
```
## Compliant Solution
Access to existing key directly and set new value.
Instead of delete key should set a value that represents blank or initial value.
```bsl
// @strict-types
Procedure Correct1() Export
TestStucture = Constructor();
TestStucture.Key1 = false;
TestStucture.Key2 = -1;
EndProcedure
// Returns:
// Structure:
// * Key1 - Boolean -
// * Key2 - Number -
Function Constructor() Export
TestStucture = new Structure("Key1, Key2", true, 10);
TestStucture.Insert("Key2", 10);
Return TestStucture;
EndFunction
```
## See

View File

@ -132,6 +132,10 @@
category="com.e1c.v8codestyle.bsl.strict"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.strict.check.TypedValueAddingToUntypedCollectionCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl.strict"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.strict.check.StructureKeyModificationCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.EventHandlerBooleanParamCheck">

View File

@ -13,12 +13,14 @@
package com.e1c.v8codestyle.bsl.comment.check;
import java.text.MessageFormat;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import com._1c.g5.v8.dt.bsl.documentation.comment.BslDocumentationComment;
import com._1c.g5.v8.dt.bsl.documentation.comment.IDescriptionPart;
import com._1c.g5.v8.dt.bsl.documentation.comment.TypeSection.FieldDefinition;
import com._1c.g5.v8.dt.bsl.documentation.comment.TypeSection.TypeDefinition;
import com._1c.g5.v8.dt.common.StringUtils;
import com._1c.g5.v8.dt.core.platform.IBmModelManager;
import com._1c.g5.v8.dt.core.platform.IResourceLookup;
@ -84,5 +86,35 @@ public class FieldDefinitionNameCheck
resultAceptor.addIssue(message, fieldDef.getLineNumber(), fieldDef.getNameOffset(),
fieldDef.getName().length());
}
else if (!isUnique(fieldDef))
{
String message = MessageFormat.format(Messages.FieldDefinitionNameCheck_Field_name__N__is_not_unique,
fieldDef.getName());
resultAceptor.addIssue(message, fieldDef.getLineNumber(), fieldDef.getNameOffset(),
fieldDef.getName().length());
}
}
private boolean isUnique(FieldDefinition fieldDef)
{
IDescriptionPart parent = fieldDef.getParent();
if (parent instanceof TypeDefinition)
{
List<FieldDefinition> fields = ((TypeDefinition)parent).getFieldDefinitionExtension();
String name = fieldDef.getName();
for (FieldDefinition field : fields)
{
if (field == fieldDef)
{
return true;
}
else if (name.equalsIgnoreCase(field.getName()))
{
return false;
}
}
}
return true;
}
}

View File

@ -37,6 +37,7 @@ final class Messages
public static String ExportMethodCommentDescriptionCheck_title;
public static String FieldDefinitionNameCheck_description;
public static String FieldDefinitionNameCheck_Field_name__N__is_incorrect_name;
public static String FieldDefinitionNameCheck_Field_name__N__is_not_unique;
public static String FieldDefinitionNameCheck_title;
public static String FieldDefinitionTypeCheck_description;
public static String FieldDefinitionTypeCheck_Field_M_has_no_type_definition;

View File

@ -40,6 +40,8 @@ ExportMethodCommentDescriptionCheck_title=Missing Description section in the com
FieldDefinitionNameCheck_Field_name__N__is_incorrect_name = Field name "{0}" is incorrect name
FieldDefinitionNameCheck_Field_name__N__is_not_unique = Field name "{0}" is not unique
FieldDefinitionNameCheck_description = Documentation comment field is correct name
FieldDefinitionNameCheck_title = Documentation comment field is correct name

View File

@ -40,6 +40,8 @@ ExportMethodCommentDescriptionCheck_title=В комментарии к эксп
FieldDefinitionNameCheck_Field_name__N__is_incorrect_name = Имя поля "{0}" является некорректным
FieldDefinitionNameCheck_Field_name__N__is_not_unique = Имя поля "{0}" не уникально
FieldDefinitionNameCheck_description = Поле документирующего комментария является корректным именем
FieldDefinitionNameCheck_title = Поле документирующего комментария является корректным именем

View File

@ -58,6 +58,14 @@ final class Messages
public static String StructureCtorValueTypeCheck_Structure_key__N__K__has_no_default_value_initializer;
public static String StructureCtorValueTypeCheck_Structure_key__N__K__value_initialized_with_empty_types;
public static String StructureCtorValueTypeCheck_title;
public static String StructureKeyModificationCheck_Check_Clear_method;
public static String StructureKeyModificationCheck_Check_Delete_method;
public static String StructureKeyModificationCheck_Check_Insert_method;
public static String StructureKeyModificationCheck_description;
public static String StructureKeyModificationCheck_error_message_Clear;
public static String StructureKeyModificationCheck_error_message_Delete;
public static String StructureKeyModificationCheck_error_message_Insert;
public static String StructureKeyModificationCheck_title;
public static String TypedValueAddingToUntypedCollectionCheck_description;
public static String TypedValueAddingToUntypedCollectionCheck_title;
public static String VariableTypeCheck_description;

View File

@ -0,0 +1,281 @@
/*******************************************************************************
* 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
*******************************************************************************/
package com.e1c.v8codestyle.bsl.strict.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.DYNAMIC_FEATURE_ACCESS;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.FEATURE_ACCESS__NAME;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.util.Pair;
import com._1c.g5.v8.bm.core.IBmTransaction;
import com._1c.g5.v8.dt.bsl.common.IBslPreferences;
import com._1c.g5.v8.dt.bsl.common.IStaticExpressionValueComputer;
import com._1c.g5.v8.dt.bsl.common.IStringLiteralTextProvider;
import com._1c.g5.v8.dt.bsl.model.BslDerivedPropertySource;
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.Invocation;
import com._1c.g5.v8.dt.bsl.model.Method;
import com._1c.g5.v8.dt.bsl.model.util.BslUtil;
import com._1c.g5.v8.dt.common.StringUtils;
import com._1c.g5.v8.dt.core.platform.IBmModelManager;
import com._1c.g5.v8.dt.core.platform.IResourceLookup;
import com._1c.g5.v8.dt.mcore.DerivedProperty;
import com._1c.g5.v8.dt.mcore.Property;
import com._1c.g5.v8.dt.mcore.TypeItem;
import com._1c.g5.v8.dt.mcore.util.Environments;
import com._1c.g5.v8.dt.mcore.util.McoreUtil;
import com._1c.g5.v8.dt.platform.IEObjectTypeNames;
import com.e1c.g5.dt.core.api.naming.INamingService;
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.google.inject.Inject;
/**
* The check of structure key modification using methods Clear(), Delete() and Insert()
* for structure created with external constructor function.
*
* @author Dmitriy Marmyshev
*/
public class StructureKeyModificationCheck
extends AbstractTypeCheck
{
private static final String CHECK_ID = "structure-key-modification"; //$NON-NLS-1$
private static final String PARAM_CHECK_INSERT = "checkInsert"; //$NON-NLS-1$
private static final String PARAM_CHECK_DELETE = "checkDelete"; //$NON-NLS-1$
private static final String PARAM_CHECK_CLEAR = "checkClear"; //$NON-NLS-1$
private static final String INSERT_RU = "Вставить"; //$NON-NLS-1$
private static final String INSERT = "Insert"; //$NON-NLS-1$
private static final String CLEAR_RU = "Очистить"; //$NON-NLS-1$
private static final String CLEAR = "Clear"; //$NON-NLS-1$
private static final String DELETE_RU = "Удалить"; //$NON-NLS-1$
private static final String DELETE = "Delete"; //$NON-NLS-1$
private static final String MODULE_URI_FRAGMENT = "/0"; //$NON-NLS-1$
private final IStaticExpressionValueComputer staticExpressionValueComputer;
@Inject
public StructureKeyModificationCheck(IResourceLookup resourceLookup, IBslPreferences bslPreferences,
IQualifiedNameConverter qualifiedNameConverter, INamingService namingService, IBmModelManager bmModelManager,
IStaticExpressionValueComputer staticExpressionValueComputer)
{
super(resourceLookup, bslPreferences, qualifiedNameConverter, namingService, bmModelManager);
this.staticExpressionValueComputer = staticExpressionValueComputer;
}
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.StructureKeyModificationCheck_title)
.description(Messages.StructureKeyModificationCheck_description)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MAJOR)
.issueType(IssueType.CODE_STYLE)
.extension(new ModuleTopObjectNameFilterExtension())
.extension(new StrictTypeAnnotationCheckExtension())
.module()
.checkedObjectType(DYNAMIC_FEATURE_ACCESS)
.parameter(PARAM_CHECK_INSERT, Boolean.class, Boolean.TRUE.toString(),
Messages.StructureKeyModificationCheck_Check_Insert_method)
.parameter(PARAM_CHECK_DELETE, Boolean.class, Boolean.TRUE.toString(),
Messages.StructureKeyModificationCheck_Check_Delete_method)
.parameter(PARAM_CHECK_CLEAR, Boolean.class, Boolean.TRUE.toString(),
Messages.StructureKeyModificationCheck_Check_Clear_method);
}
@Override
protected void check(Object object, ResultAcceptor resultAcceptor, ICheckParameters parameters,
IBmTransaction bmTransaction, IProgressMonitor monitor)
{
DynamicFeatureAccess fa = (DynamicFeatureAccess)object;
String methodName = fa.getName();
if (StringUtils.isBlank(methodName))
{
return;
}
Invocation inv = BslUtil.getInvocation(fa);
if (inv == null)
{
return;
}
Expression source = fa.getSource();
boolean isInsert = isInsert(methodName);
if (parameters.getBoolean(PARAM_CHECK_INSERT) && isInsert
|| parameters.getBoolean(PARAM_CHECK_DELETE) && isDelete(methodName))
{
if (inv.getParams().isEmpty())
{
return;
}
Environments actualEnvs = getActualEnvironments(fa);
if (actualEnvs.isEmpty())
{
return;
}
List<TypeItem> sourceTypes = computeTypes(source, actualEnvs).stream()
.filter(t -> IEObjectTypeNames.STRUCTURE.equals(McoreUtil.getTypeName(t)))
.collect(Collectors.toList());
if (sourceTypes.isEmpty())
{
return;
}
IStringLiteralTextProvider structureKey =
staticExpressionValueComputer.getStringContent(inv.getParams().get(0));
if (structureKey != null && StringUtils.isNotBlank(structureKey.getText()))
{
String keyName = structureKey.getText();
if (isExternalStructureKey(sourceTypes, source, keyName, monitor))
{
String message = isInsert ? Messages.StructureKeyModificationCheck_error_message_Insert
: Messages.StructureKeyModificationCheck_error_message_Delete;
message = MessageFormat.format(message, keyName);
resultAcceptor.addIssue(message, FEATURE_ACCESS__NAME);
}
}
}
else if (parameters.getBoolean(PARAM_CHECK_CLEAR) && inv.getParams().isEmpty() && isClear(methodName))
{
Environments actualEnvs = getActualEnvironments(fa);
if (actualEnvs.isEmpty())
{
return;
}
List<TypeItem> sourceTypes = computeTypes(source, actualEnvs).stream()
.filter(t -> IEObjectTypeNames.STRUCTURE.equals(McoreUtil.getTypeName(t)))
.collect(Collectors.toList());
if (sourceTypes.isEmpty())
{
return;
}
Optional<DerivedProperty> firstProperty = getFirstExternalKey(sourceTypes, fa);
if (!monitor.isCanceled() && firstProperty.isPresent())
{
String message = Messages.StructureKeyModificationCheck_error_message_Clear;
resultAcceptor.addIssue(message, FEATURE_ACCESS__NAME);
}
}
}
private Optional<DerivedProperty> getFirstExternalKey(List<TypeItem> sourceTypes, Expression context)
{
return dynamicFeatureAccessComputer.getAllProperties(sourceTypes, context.eResource())
.stream()
.flatMap(e -> e.getFirst().stream())
.filter(e -> e instanceof DerivedProperty
&& ((DerivedProperty)e).getSource() instanceof BslDerivedPropertySource
&& isExternalStructureKey((DerivedProperty)e, context))
.map(DerivedProperty.class::cast)
.findAny();
}
private boolean isExternalStructureKey(Collection<TypeItem> structureTypes, Expression currentMethodObject,
String keyName, IProgressMonitor monitor)
{
Collection<Pair<Collection<Property>, TypeItem>> allProperties =
dynamicFeatureAccessComputer.getAllProperties(structureTypes, currentMethodObject.eResource());
for (Pair<Collection<Property>, TypeItem> pair : allProperties)
{
for (Property property : pair.getFirst())
{
if (monitor.isCanceled())
{
return false;
}
if (property instanceof DerivedProperty && keyName.equalsIgnoreCase(property.getName())
&& ((DerivedProperty)property).getSource() instanceof BslDerivedPropertySource)
{
return isExternalStructureKey((DerivedProperty)property, currentMethodObject);
}
}
}
return false;
}
private boolean isExternalStructureKey(DerivedProperty property, Expression currentMethodObject)
{
BslDerivedPropertySource source = (BslDerivedPropertySource)property.getSource();
URI uri = EcoreUtil.getURI(currentMethodObject).trimFragment().appendFragment(MODULE_URI_FRAGMENT);
if (source.getModuleUri() != null && !source.getModuleUri().equals(uri.toString()))
{
return true;
}
Method method = EcoreUtil2.getContainerOfType(currentMethodObject, Method.class);
String currentMethodName = method == null ? StringUtils.EMPTY : method.getName();
if (!currentMethodName.equalsIgnoreCase(source.getMethodName()))
{
return true;
}
else if (source.getLocalOffset() > 0 && method != null)
{
ICompositeNode node = NodeModelUtils.findActualNodeFor(method);
return source.getLocalOffset() < node.getOffset() - node.getTotalOffset();
}
return false;
}
private boolean isDelete(String methodName)
{
return DELETE_RU.equalsIgnoreCase(methodName) || DELETE.equalsIgnoreCase(methodName);
}
private boolean isInsert(String methodName)
{
return INSERT_RU.equalsIgnoreCase(methodName) || INSERT.equalsIgnoreCase(methodName);
}
private boolean isClear(String methodName)
{
return CLEAR_RU.equalsIgnoreCase(methodName) || CLEAR.equalsIgnoreCase(methodName);
}
}

View File

@ -84,6 +84,22 @@ StructureCtorValueTypeCheck_description = Checks Structure constructor string li
StructureCtorValueTypeCheck_title = Structure constructor value types
StructureKeyModificationCheck_Check_Clear_method = Check Clear() method
StructureKeyModificationCheck_Check_Delete_method = Check Delete() method
StructureKeyModificationCheck_Check_Insert_method = Check Insert() method
StructureKeyModificationCheck_description = Structure key modification outside constructor function
StructureKeyModificationCheck_error_message_Clear = Should not clear external structure keys
StructureKeyModificationCheck_error_message_Delete = Should not delete external structure key "{0}"
StructureKeyModificationCheck_error_message_Insert = Should not replace external structure key "{0}" with new value type
StructureKeyModificationCheck_title = Structure key modification outside constructor function
TypedValueAddingToUntypedCollectionCheck_description = Typed value is added to untyped collection
TypedValueAddingToUntypedCollectionCheck_title = Typed value is added to untyped collection

View File

@ -84,6 +84,22 @@ StructureCtorValueTypeCheck_description = Проверяет строковый
StructureCtorValueTypeCheck_title = Типизация значений в конструкторе структуры
StructureKeyModificationCheck_Check_Clear_method = Проверять метод Очистить()
StructureKeyModificationCheck_Check_Delete_method = Проверять метод Удалить()
StructureKeyModificationCheck_Check_Insert_method = Проверять метод Вставить()
StructureKeyModificationCheck_description = Модификация ключа структуры вне функции-конструктора
StructureKeyModificationCheck_error_message_Clear = Нельзя очищать ключи внешней структуры
StructureKeyModificationCheck_error_message_Delete = Нельзя удалять ключ "{0}" внешней структуры
StructureKeyModificationCheck_error_message_Insert = Нельзя заменять ключ "{0}" внешней структуры новым типом значения
StructureKeyModificationCheck_title = Модификация ключа структуры вне функции-конструктора
TypedValueAddingToUntypedCollectionCheck_description = Добавление типизированного значения в нетипизированную коллекцию
TypedValueAddingToUntypedCollectionCheck_title = Добавление типизированного значения в нетипизированную коллекцию

View File

@ -27,6 +27,7 @@ import org.eclipse.xtext.scoping.IScopeProvider;
import com._1c.g5.v8.dt.bm.xtext.BmAwareResourceSetProvider;
import com._1c.g5.v8.dt.bsl.common.IBslPreferences;
import com._1c.g5.v8.dt.bsl.common.IStaticExpressionValueComputer;
import com._1c.g5.v8.dt.bsl.contextdef.IBslModuleContextDefService;
import com._1c.g5.v8.dt.bsl.documentation.comment.BslMultiLineCommentDocumentationProvider;
import com._1c.g5.v8.dt.bsl.model.resource.owner.IBslOwnerComputerService;
@ -100,5 +101,6 @@ class ExternalDependenciesModule
bind(IConfigurationProvider.class).toService();
bind(BslGrammarAccess.class).toProvider(() -> rsp.get(BslGrammarAccess.class));
bind(BmAwareResourceSetProvider.class).toProvider(() -> rsp.get(BmAwareResourceSetProvider.class));
bind(IStaticExpressionValueComputer.class).toProvider(() -> rsp.get(IStaticExpressionValueComputer.class));
}
}

View File

@ -1,170 +1,6 @@
CommonModuleNameClientServer_description = Client-server common module should end with ClientServer suffix
CommonModuleNameClientServer_message = Client-server common module should end with "{0}" suffix
CommonModuleNameClientServer_title = Client-server common module should end with ClientServer suffix
CommonModuleNameClient_description = Client common module should end with Client suffix
CommonModuleNameClient_message = Client common module name should end with "{0}" suffix
CommonModuleNameClient_title = Client common module should end with Client suffix
CommonModuleNameGlobalClientCheck_Description = Global common module should end with Global suffix
CommonModuleNameGlobalClientCheck_Message = Global common module should not have "{0}" suffix
CommonModuleNameGlobalClientCheck_Title = Global common module should end with Global suffix
CommonModuleNameGlobal_Description = Global common module should end with Global suffix
CommonModuleNameGlobal_Message = Global common module should end with "{0}" suffix
CommonModuleNameGlobal_Title = Global common module should end with Global suffix
CommonModuleNamePrivilegedCheck_Description = Privileged common module should end with FullAccess suffix
CommonModuleNamePrivilegedCheck_Issue = Privileged common module should end with "{0}" suffix
CommonModuleNamePrivilegedCheck_Title = Privileged common module should end with FullAccess suffix
CommonModuleNameServerCallPostfixCheck_0 = Common module should end with {0}
CommonModuleNameServerCallPostfixCheck_Common_module_name_description = Common module should end with correct postfix
CommonModuleNameServerCallPostfixCheck_Common_module_postfix_title = Common module should end with correct postfix
CommonModuleType_description = Common module has incorrect type
CommonModuleType_message = Common module for type "{0}" has incorrect settings: {1}
CommonModuleType_title = Common module has incorrect type
ConfigurationDataLock_description = Application should use managed data lock mode
ConfigurationDataLock_message = Application should use managed data lock mode
ConfigurationDataLock_title = Configuration data lock mode
DbObjectAnyRefCheck_AnyRef = Do not use composite types AnyRef, CatalogRef, DocumentRef, and other for standard metadata objects stored in the infobase.
DbObjectAnyRefCheck_Description = Do not use composite types AnyRef, CatalogRef, DocumentRef, and other for standard metadata objects stored in the infobase.
DbObjectAnyRefCheck_Title = Restrictions on the use of any ref type attributes
DbObjectRefNonRefTypesCheck_Description = Composite type attributes used in join conditions, filters, and for ordering must contain only reference attribute types (CatalogRef. ..., DocumentRef. ..., and other). Do not include any other non-reference types in this type. For example: String, Number, Date, UUID, Boolean, and ValueStorage.
DbObjectRefNonRefTypesCheck_Ref_and_other = Composite type attributes used in join conditions, filters, and for ordering must contain only reference attribute types (CatalogRef. ..., DocumentRef. ..., and other). Do not include any other non-reference types in this type.
DbObjectRefNonRefTypesCheck_Title = Restrictions on the use of composite type attributes
DocumentPostInPrivilegedModeCheck_title = In document that allow posting don't set flag "Post/Unpost in privileged mode"
DocumentPostInPrivilegedModeCheck_description = In document that allow posting don't set flag "Post/Unpost in privileged mode"
DocumentPostInPrivilegedModeCheck_message_Post_in_privileged_mode = In document that allow posting don't set flag "Post in privileged mode"
DocumentPostInPrivilegedModeCheck_message_Unpost_in_privileged_mode = In document that allow posting don't set flag "Unpost in privileged mode"
ExtensionMdObjectNamePrefixCheck_Description = The object name of the extension object does not have a prefix corresponding to the prefix of the extension itself
ExtensionMdObjectNamePrefixCheck_Object_0_should_have_1_prefix = The object "{0}" should have "{1}" prefix
ExtensionMdObjectNamePrefixCheck_Title = Extension object name does not have extension prefix
FunctionalOptionPrivilegedGetModeCheck_message = Functional option don't use privileged get mode
FunctionalOptionPrivilegedGetModeCheck_description = Functional option don't use privileged get mode
FunctionalOptionPrivilegedGetModeCheck_title = Functional option don't use privileged get mode
MdListObjectPresentationCheck_Neither_Object_presentation_nor_List_presentation_is_not_filled = Neither Object presentation nor List presentation is not filled
MdListObjectPresentationCheck_decription = Neither Object presentation nor List presentation is not filled
MdListObjectPresentationCheck_title = Neither Object presentation nor List presentation is not filled
MdObjectAttributeCommentCheck_Attribute_list=Attributes list
MdObjectAttributeCommentCheck_Check_catalogs_param=Check Catalogs
MdObjectAttributeCommentCheck_Check_documents_param=Check Documents
MdObjectAttributeCommentCheck_Default_check_message=The attribute "Comment" has an invalid type
MdObjectAttributeCommentCheck_description=The attribute "Comment" has an invalid type
MdObjectAttributeCommentCheck_title=The attribute "Comment" has an invalid type
MdObjectAttributeCommentNotExist_Md_Object_attribute_Comment_does_not_exist = Md Object attribute "Comment" does not exist
MdObjectAttributeCommentNotExist_Param_Attribute_name_list = Attribute name list
MdObjectAttributeCommentNotExist_Param_Check_Catalogs = Check catalogs
MdObjectAttributeCommentNotExist_Param_Check_Documents = Check documents
MdObjectAttributeCommentNotExist_description = Md Object attribute "Comment" does not exist
MdObjectAttributeCommentNotExist_title = Md Object attribute "Comment" does not exist
MdObjectNameLength_Maximum_name_length_description = Maximum name length
MdObjectNameLength_description = Metadata object name length should be less than {0}
MdObjectNameLength_message = Metadata object name should be less then {0}
MdObjectNameLength_title = Metadata object name length
MdObjectNameUnallowedLetterCheck_Ru_locale_unallowed_letter_used_for_name_synonym_or_comment = In Russian locale, name, synonym or comment of metadata object contain the unallowed letter
MdObjectNameUnallowedLetterCheck_description = In Russian locale name, synonym or comment of metadata object contain the unallowed letter
MdObjectNameUnallowedLetterCheck_title = In Russian locale name, synonym or comment of metadata object contain the unallowed letter
MdObjectNameWithoutSuffix_Name_suffix_list_title = Name suffix list, comma separated
MdOwnerAttributeSynonymEmpty_Description = Synonym of the 'Owner' or 'Parent' standard attribute is not specified
MdOwnerAttributeSynonymEmpty_Title = Synonym of the 'Owner' or 'Parent' standard attribute is not specified
MdOwnerAttributeSynonymEmpty_owner_ErrorMessage = Synonym of the 'Owner' standard attribute is not specified
MdOwnerAttributeSynonymEmpty_parent_ErrorMessage = Synonym of the 'Parent' standard attribute is not specified
MdScheduledJobDescriptionCheck_description = The description of the predefine sheduled job is set
MdScheduledJobDescriptionCheck_message = The description of the predefine sheduled job is set
MdScheduledJobDescriptionCheck_title = The description of the predefine sheduled job is set
MdScheduledJobPeriodicityCheck_Minimum_job_interval_description = Minimum job interval
MdScheduledJobPeriodicityCheck_The_minimum_job_interval_is_less_then_minute = The minimum job interval is less then {0}s
MdScheduledJobPeriodicityCheck_description = The minimum job interval is less then {0}s
MdScheduledJobPeriodicityCheck_title = The minimum job interval is less then {0}s
RegisterResourcePrecisionCheck_description = Accumulation or accounting register resource precision is more than 25
RegisterResourcePrecisionCheck_message = Accumulation or accounting register resource "{0}" precision is more than {1}
RegisterResourcePrecisionCheck_title = Accumulation or accounting register resource precision is more than 25
SubsystemSynonymTooLongCheck_Exclude_languages_comma_separated = Exclude languages (codes, comma-separated)
SubsystemSynonymTooLongCheck_Length_of_section_name_more_than_symbols_for_language = Length of section synonym "{0}" more than {1} symbols for language {2}
SubsystemSynonymTooLongCheck_Maximum_section_name_length = Maximum section name length
SubsystemSynonymTooLongCheck_description = Section name is more than 35 characters long
SubsystemSynonymTooLongCheck_title = Section name is more than 35 characters long
UnsafePasswordStorageCheck_Avoid_storing_password_in_infobase = Avoid storing passwords in the infobase
UnsafePasswordStorageCheck_Avoid_storing_password_in_infobase_description = To minimize risks of unauthorized access to passwords, avoid storing passwords in the infobase.
UnsafePasswordStorageCheck_Avoid_storing_password_in_infobase_error = Avoid storing passwords in the infobase

View File

@ -1,171 +1,7 @@
#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/)
CommonModuleNameClientServer_description = Клиент-серверный общий модуль должен оканчиваться на суффикс КлиентСервер
CommonModuleNameClientServer_message = Клиент-серверный общий модуль должен оканчиваться на суффикс "{0}"
CommonModuleNameClientServer_title = Клиент-серверный общий модуль должен оканчиваться на суффикс КлиентСервер
CommonModuleNameClient_description = Клиентский общий модуль должен оканчиваться на суффикс Клиент
CommonModuleNameClient_message = Клиентский общий модуль должен оканчиваться на суффикс "{0}"
CommonModuleNameClient_title = Клиентский общий модуль должен оканчиваться на суффикс Клиент
CommonModuleNameGlobalClientCheck_Description = Глобальный общий модуль должен оканчиваться на суффикс Глобальный
CommonModuleNameGlobalClientCheck_Message = Глобальный общий модуль не должен содержать суффикс "{0}"
CommonModuleNameGlobalClientCheck_Title = Глобальный общий модуль должен оканчиваться на суффикс Глобальный
CommonModuleNameGlobal_Description = Глобальный общий модуль должен оканчиваться на суффикс Глобальный
CommonModuleNameGlobal_Message = Глобальный общий модуль должен оканчиваться на суффикс "{0}"
CommonModuleNameGlobal_Title = Глобальный общий модуль должен оканчиваться на суффикс Глобальный
CommonModuleNamePrivilegedCheck_Description = Привилегированный модуль должен оканчиваться на суффикс ПолныеПрава
CommonModuleNamePrivilegedCheck_Issue = Привилегированный модуль должен оканчиваться на суффикс "{0}"
CommonModuleNamePrivilegedCheck_Title = Привилегированный модуль должен оканчиваться на суффикс ПолныеПрава
CommonModuleNameServerCallPostfixCheck_0 = Общий модуль должен именоваться с постфиксом {0}
CommonModuleNameServerCallPostfixCheck_Common_module_name_description = Общий модуль должен именоваться с постфиксом
CommonModuleNameServerCallPostfixCheck_Common_module_postfix_title = Общий модуль должен именоваться с постфиксом
CommonModuleType_description = Общий модуль имеет некорректный тип
CommonModuleType_message = Общий модуль для типа "{0}" имеет некорректные настройки: {1}
CommonModuleType_title = Общий модуль имеет некорректный тип
ConfigurationDataLock_description = Приложение должно использовать управляемый режим блокировки данных
ConfigurationDataLock_message = Приложение должно использовать управляемый режим блокировки данных
ConfigurationDataLock_title = Режим блокировки данных конфигурации
DbObjectAnyRefCheck_AnyRef = Для типизированных объектов метаданных, хранящихся в информационной базе, не следует использовать составные типы ЛюбаяСсылка, СправочникСсылка, ДокументСсылка и аналогичные.
DbObjectAnyRefCheck_Description = Для типизированных объектов метаданных, хранящихся в информационной базе, не следует использовать составные типы ЛюбаяСсылка, СправочникСсылка, ДокументСсылка и аналогичные. Состав типов того или иного типизированного объекта должен определяться явным образом.
DbObjectAnyRefCheck_Title = Использование составного типа, содержащего ЛюбаяСсылка и аналогичные.
DbObjectRefNonRefTypesCheck_Description = Реквизиты составного типа, используемые в условиях соединений, отборах, а также для упорядочивания, должны содержать только ссылочные типы (СправочникСсылка.…, ДокументСсылка.… и пр.). В состав их типов не рекомендуется включать никаких других нессылочных типов, например: Строка, Число, Дата, УникальныйИдентификатор, Булево, а также ХранилищеЗначения.
DbObjectRefNonRefTypesCheck_Ref_and_other = Реквизиты составного типа, используемые в условиях соединений, отборах, а также для упорядочивания, должны содержать только ссылочные типы (СправочникСсылка.…, ДокументСсылка.… и пр.). В состав их типов не рекомендуется включать никаких других нессылочных типов.
DbObjectRefNonRefTypesCheck_Title = Использование составного типа, содержащего ссылочные и не ссылочный тип вместе.
DocumentPostInPrivilegedModeCheck_description = В документе, предполагающем проведение, не стоит флаг "Прив. режим при проведении/отмене проведения"
DocumentPostInPrivilegedModeCheck_message_Post_in_privileged_mode = В документе, предполагающем проведение, не стоит флаг "Прив. режим при проведении"
DocumentPostInPrivilegedModeCheck_message_Unpost_in_privileged_mode = В документе, предполагающем проведение, не стоит флаг "Прив. режим при отмене проведения"
DocumentPostInPrivilegedModeCheck_title = В документе, предполагающем проведение, не стоит флаг "Прив. режим при проведении/отмене проведения"
ExtensionMdObjectNamePrefixCheck_Description = Имя объекта в расширении не содержит префикс расширения
ExtensionMdObjectNamePrefixCheck_Object_0_should_have_1_prefix = Имя объекта "{0}" должно содержать префикс "{1}"
ExtensionMdObjectNamePrefixCheck_Title = Имя объекта в расширении должно содержать префикс расширения
FunctionalOptionPrivilegedGetModeCheck_message = В функциональной опции не установлен флаг "Привилегированный режим при получении"
FunctionalOptionPrivilegedGetModeCheck_description = В функциональной опции не установлен флаг "Привилегированный режим при получении"
FunctionalOptionPrivilegedGetModeCheck_title = В функциональной опции не установлен флаг "Привилегированный режим при получении"
MdListObjectPresentationCheck_Neither_Object_presentation_nor_List_presentation_is_not_filled = Не заполнено ни представление объекта, ни представление списка
MdListObjectPresentationCheck_decription = Не заполнено ни представление объекта, ни представление списка
MdListObjectPresentationCheck_title = Не заполнено ни представление объекта, ни представление списка
MdObjectAttributeCommentCheck_Attribute_list = Список реквизитов
MdObjectAttributeCommentCheck_Check_catalogs_param = Проверять справочники
MdObjectAttributeCommentCheck_Check_documents_param = Проверять документы
MdObjectAttributeCommentCheck_Default_check_message = Реквизит "Комментарий" имеет недопустимый тип
MdObjectAttributeCommentCheck_description = Реквизит "Комментарий" имеет недопустимый тип
MdObjectAttributeCommentCheck_title = Реквизит "Комментарий" имеет недопустимый тип
MdObjectAttributeCommentNotExist_Md_Object_attribute_Comment_does_not_exist = Объект метаданных не имеет реквизит "Комментарий"
MdObjectAttributeCommentNotExist_Param_Attribute_name_list = Список имен реквизита
MdObjectAttributeCommentNotExist_Param_Check_Catalogs = Проверять справочники
MdObjectAttributeCommentNotExist_Param_Check_Documents = Проверять документы
MdObjectAttributeCommentNotExist_description = Объект метаданных не имеет реквизит "Комментарий"
MdObjectAttributeCommentNotExist_title = Объект метаданных не имеет реквизит "Комментарий"
MdObjectNameLength_Maximum_name_length_description = Максимальная длина имени
MdObjectNameLength_description = Длина имени объекта метаданного должна быть меньше чем {0}
MdObjectNameLength_message = Длина имени объекта метаданного должна быть меньше чем {0}
MdObjectNameLength_title = Длина имени объекта метаданных
MdObjectNameUnallowedLetterCheck_Ru_locale_unallowed_letter_used_for_name_synonym_or_comment = Имя, синоним или комментарий содержит букву “ё”
MdObjectNameUnallowedLetterCheck_description = Имя, синоним или комментарий содержит букву “ё”
MdObjectNameUnallowedLetterCheck_title = Имя, синоним или комментарий содержит букву “ё”
MdObjectNameWithoutSuffix_Name_suffix_list_title = Список суффиксов имени, разделенный запятой
MdOwnerAttributeSynonymEmpty_Description = Не задан синоним у стандартного свойства 'Владелец' или 'Родитель'
MdOwnerAttributeSynonymEmpty_Title = Не задан синоним у стандартного свойства 'Владелец' или 'Родитель'
MdOwnerAttributeSynonymEmpty_owner_ErrorMessage = Не задан синоним у стандартного реквизита 'Владелец'
MdOwnerAttributeSynonymEmpty_parent_ErrorMessage = Не задан синоним у стандартного реквизита 'Родитель'
MdScheduledJobDescriptionCheck_description = Задано наименование предопределенного регламентного задания
MdScheduledJobDescriptionCheck_message = Задано наименование предопределенного регламентного задания
MdScheduledJobDescriptionCheck_title = Задано наименование предопределенного регламентного задания
MdScheduledJobPeriodicityCheck_Minimum_job_interval_description = Минимальный интервал выполнения
MdScheduledJobPeriodicityCheck_The_minimum_job_interval_is_less_then_minute = Периодичность выполнения регламентного задания меньше {0}сек
MdScheduledJobPeriodicityCheck_description = Периодичность выполнения регламентного задания меньше {0}сек
MdScheduledJobPeriodicityCheck_title = Периодичность выполнения регламентного задания меньше {0}сек
RegisterResourcePrecisionCheck_description = Превышена максимальная длина ресурса регистра накопления или бухгалтерии (25 знаков)
RegisterResourcePrecisionCheck_message = Длина ресурса регистра "{0}" превышает {1}
RegisterResourcePrecisionCheck_title = Превышена максимальная длина ресурса регистра накопления или бухгалтерии (25 знаков)
SubsystemSynonymTooLongCheck_Exclude_languages_comma_separated = Исключить языки (коды, разделенных запятыми)
SubsystemSynonymTooLongCheck_Length_of_section_name_more_than_symbols_for_language = Длина синонима раздела "{0}" превышает {1} символов для языка {2}
SubsystemSynonymTooLongCheck_Maximum_section_name_length = Максимальная длина названия раздела верхнего уровня
SubsystemSynonymTooLongCheck_description = Длина названия раздела превышает 35 символов
SubsystemSynonymTooLongCheck_title = Длина названия раздела превышает 35 символов
UnsafePasswordStorageCheck_Avoid_storing_password_in_infobase = Не следует хранить пароли в информационной базе
UnsafePasswordStorageCheck_Avoid_storing_password_in_infobase_description = Для сведения к минимуму возможности перехвата пароля злоумышленниками не следует хранить пароли в информационной базе
UnsafePasswordStorageCheck_Avoid_storing_password_in_infobase_error = Не следует хранить пароли в информационной базе

View File

@ -0,0 +1,19 @@
// Parameters:
// Parameter1 - Structure:
// * Name - correct name
// * Name - incorrect name, ununique
//
Procedure NonComplaint(Parameter1)
EndProcedure
// Parameters:
// Parameter1 - Structure:
// * Name - correct name
//
Procedure Complaint(Parameter1)
EndProcedure

View File

@ -0,0 +1,65 @@
// @strict-types
Procedure Incorrect1() Export
TestStucture = Correct2();
TestStucture.Clear();
TestStucture.Delete("Key2");
TestStucture.Insert("Key1", Undefined);
TestStucture.Clear();
TestStucture.Insert("Key1", 10);
TestStucture.Key1 = "";
EndProcedure
Procedure Correct1() Export
TestStucture = new Structure();
TestStucture.Clear();
TestStucture.Delete("Key2");
TestStucture.Insert("Key1");
TestStucture.Clear();
TestStucture.Insert("Key1", 10);
TestStucture.Clear();
TestStucture.Key1 = "";
EndProcedure
// Parameters:
// TestStucture - Structure:
// * Key1 - Boolean -
// * Key2 - Number -
Procedure Incorrect2(TestStucture) Export
TestStucture.Insert("Key1", 10);
TestStucture.Insert("Key3", 10);
TestStucture.Clear();
TestStucture.Delete("Key2");
EndProcedure
// Parameters:
// TestStucture - See Correct2
Procedure Incorrect3(TestStucture) Export
TestStucture.Insert("Key1", 10);
TestStucture.Insert("Key3", 10);
TestStucture.Clear();
TestStucture.Delete("Key2");
EndProcedure
// Returns:
// Structure:
// * Key1 - Boolean -
// * Key2 - Number -
Function Correct2() Export
TestStucture = new Structure("Key1, Key2", true, 10);
TestStucture.Insert("Key1", 10);
Return TestStucture;
EndFunction

View File

@ -52,4 +52,20 @@ public class FieldDefinitionNameCheckTest
Marker marker = markers.get(0);
assertEquals("4", marker.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
/**
* Test the documentation comment field name is unique name
*
* @throws Exception the exception
*/
@Test
public void testInvalidFieldNameUnunique() throws Exception
{
updateModule(FOLDER_RESOURCE + "doc-comment-field-name-ununique.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals("5", marker.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
}

View File

@ -55,6 +55,7 @@ import com.e1c.v8codestyle.bsl.strict.check.InvocationParamIntersectionCheck;
import com.e1c.v8codestyle.bsl.strict.check.MethodParamTypeCheck;
import com.e1c.v8codestyle.bsl.strict.check.SimpleStatementTypeCheck;
import com.e1c.v8codestyle.bsl.strict.check.StructureCtorValueTypeCheck;
import com.e1c.v8codestyle.bsl.strict.check.StructureKeyModificationCheck;
import com.e1c.v8codestyle.bsl.strict.check.TypedValueAddingToUntypedCollectionCheck;
import com.e1c.v8codestyle.bsl.strict.check.VariableTypeCheck;
@ -643,6 +644,33 @@ public class CommonModuleStrictTypesTest
assertEquals(Set.of("18", "19"), lines);
}
/**
* Test of {@link StructureKeyModificationCheck} that check replace existing key of external structure key,
* delete key or clear structure with existing keys.
*
* @throws Exception the exception
*/
@Test
public void testStructureKeyModification() throws Exception
{
String checkId = "structure-key-modification";
String resouceName = "structure-key-modification";
Module module = updateAndGetModule(resouceName);
List<Marker> markers = getMarters(checkId, module);
assertEquals(10, markers.size());
Set<String> lines = new HashSet<>();
for (Marker marker : markers)
{
lines.add(marker.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
assertEquals(Set.of("7", "8", "9", "10", "36", "38", "39", "47", "49", "50"), lines);
}
private IDtProject getProject()
{
return dtProject;