mirror of
https://github.com/1C-Company/v8-code-style.git
synced 2025-04-04 09:49:40 +02:00
This commit is contained in:
parent
3218c8665c
commit
dad25b744f
@ -19,6 +19,8 @@
|
||||
#### Код модулей
|
||||
|
||||
- Проверка на уникальность имени поля в doc-comment-field-name #1392
|
||||
- Проверка модификации ключей структуры вне функции-конструктора #1054
|
||||
|
||||
|
||||
#### Запросы
|
||||
|
||||
|
@ -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);
|
||||
|
||||
Возврат ТестоваяСтруктура;
|
||||
|
||||
КонецФункции
|
||||
```
|
||||
|
||||
## См.
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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 = Добавление типизированного значения в нетипизированную коллекцию
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user