mirror of
https://github.com/1C-Company/v8-code-style.git
synced 2024-12-01 02:32:18 +02:00
#790 Исключения для COM-объектов
This commit is contained in:
parent
38e5daf702
commit
59691afe7a
@ -49,6 +49,7 @@
|
||||
- Исправлен идентификатор проверки тип в строгой типизации: `doc-comment-field-type` -> `doc-comment-field-type-strict`
|
||||
- Ограничения на использование экспортных процедур и функций в модулях команд и форм
|
||||
- Вызов "Заблокировать()" находится вне попытки
|
||||
- Для проверок dynamic-access-method-not-found и property-return-type добавлена возможность исключения по типам (COM-Объекты)
|
||||
|
||||
#### Запросы
|
||||
|
||||
|
@ -0,0 +1,189 @@
|
||||
/*******************************************************************************
|
||||
* 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.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.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.xtext.EcoreUtil2;
|
||||
import org.eclipse.xtext.naming.IQualifiedNameConverter;
|
||||
|
||||
import com._1c.g5.v8.dt.bsl.common.IBslPreferences;
|
||||
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.FeatureEntry;
|
||||
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.IResourceLookup;
|
||||
import com._1c.g5.v8.dt.mcore.Environmental;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* The abstract check for {@link DynamicFeatureAccess} if method have source object, means method exist in the object,
|
||||
* or property has return value type that means property exist and has typed value.
|
||||
*
|
||||
* @author Dmitriy Marmyshev
|
||||
*/
|
||||
public abstract class AbstractDynamicFeatureAccessTypeCheck
|
||||
extends AbstractTypeCheck
|
||||
{
|
||||
private static final String DELIMITER = ","; //$NON-NLS-1$
|
||||
|
||||
private static final String PARAMETER_SKIP_SOURCE_TYPES = "skipSourceTypes"; //$NON-NLS-1$
|
||||
|
||||
private static final String DEFAULT_SKIP_SOURCE_TYPES =
|
||||
String.join(DELIMITER, Set.of(IEObjectTypeNames.COM_OBJECT));
|
||||
|
||||
/**
|
||||
* Instantiates a new dynamic feature access type check.
|
||||
*
|
||||
* @param resourceLookup the resource lookup service, cannot be {@code null}.
|
||||
* @param bslPreferences the BSL preferences service, cannot be {@code null}.
|
||||
* @param qualifiedNameConverter the qualified name converter service, cannot be {@code null}.
|
||||
*/
|
||||
protected AbstractDynamicFeatureAccessTypeCheck(IResourceLookup resourceLookup, IBslPreferences bslPreferences,
|
||||
IQualifiedNameConverter qualifiedNameConverter)
|
||||
{
|
||||
super(resourceLookup, bslPreferences, qualifiedNameConverter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureCheck(CheckConfigurer builder)
|
||||
{
|
||||
builder.title(getTitle())
|
||||
.description(getDescription())
|
||||
.complexity(CheckComplexity.NORMAL)
|
||||
.severity(IssueSeverity.MAJOR)
|
||||
.issueType(IssueType.CODE_STYLE)
|
||||
.extension(new ModuleTopObjectNameFilterExtension())
|
||||
.extension(new StrictTypeAnnotationCheckExtension())
|
||||
.module()
|
||||
.checkedObjectType(DYNAMIC_FEATURE_ACCESS)
|
||||
.parameter(PARAMETER_SKIP_SOURCE_TYPES, String.class, DEFAULT_SKIP_SOURCE_TYPES,
|
||||
Messages.AbstractDynamicFeatureAccessTypeCheck_Skip_source_object_types);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title of the check.
|
||||
*
|
||||
* @return the title, cannot return {@code null}.
|
||||
*/
|
||||
protected abstract String getTitle();
|
||||
|
||||
/**
|
||||
* Gets the description of the check.
|
||||
*
|
||||
* @return the description, cannot return {@code null}.
|
||||
*/
|
||||
protected abstract String getDescription();
|
||||
|
||||
/**
|
||||
* Checks if the {@link DynamicFeatureAccess} is method.
|
||||
*
|
||||
* @return true, if the {@link DynamicFeatureAccess} is method
|
||||
*/
|
||||
protected abstract boolean isCheckDfaMethod();
|
||||
|
||||
/**
|
||||
* Gets the error message by {@link DynamicFeatureAccess}.
|
||||
*
|
||||
* @param fa the {@link DynamicFeatureAccess} to generate message
|
||||
* @return the error message, cannot return {@code null}.
|
||||
*/
|
||||
protected abstract String getErrorMessage(DynamicFeatureAccess fa);
|
||||
|
||||
@Override
|
||||
protected final void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
|
||||
IProgressMonitor monitor)
|
||||
{
|
||||
DynamicFeatureAccess fa = (DynamicFeatureAccess)object;
|
||||
if (StringUtils.isBlank(fa.getName()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isMethod = BslUtil.getInvocation(fa) != null;
|
||||
if (isMethod == isCheckDfaMethod() && (isMethod && isEmptySource(fa) || !isMethod && isEmptyTypes(fa))
|
||||
&& !monitor.isCanceled() && !isSkipSourceType(fa, parameters, monitor))
|
||||
{
|
||||
String message = getErrorMessage(fa);
|
||||
|
||||
resultAceptor.addIssue(message, FEATURE_ACCESS__NAME);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEmptySource(DynamicFeatureAccess object)
|
||||
{
|
||||
Environmental envs = EcoreUtil2.getContainerOfType(object, Environmental.class);
|
||||
if (envs == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Environments actualEnvs = bslPreferences.getLoadEnvs(object).intersect(envs.environments());
|
||||
if (actualEnvs.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
List<FeatureEntry> objects = dynamicFeatureAccessComputer.getLastObject(object, actualEnvs);
|
||||
return objects.isEmpty();
|
||||
}
|
||||
|
||||
private boolean isSkipSourceType(DynamicFeatureAccess fa, ICheckParameters parameters, IProgressMonitor monitor)
|
||||
{
|
||||
String typesString = parameters.getString(PARAMETER_SKIP_SOURCE_TYPES);
|
||||
if (StringUtils.isBlank(typesString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> typeNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
|
||||
typeNames.addAll(List.of(typesString.split(",\\s*"))); //$NON-NLS-1$
|
||||
if (monitor.isCanceled() || typeNames.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Expression source = fa.getSource();
|
||||
|
||||
Environmental envs = EcoreUtil2.getContainerOfType(source, Environmental.class);
|
||||
if (monitor.isCanceled() || envs == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Environments actualEnvs = bslPreferences.getLoadEnvs(source).intersect(envs.environments());
|
||||
if (monitor.isCanceled() || actualEnvs.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
List<TypeItem> types = computeTypes(source, actualEnvs);
|
||||
return !monitor.isCanceled() && !types.isEmpty()
|
||||
&& types.stream().anyMatch(t -> typeNames.contains(McoreUtil.getTypeName(t)));
|
||||
}
|
||||
|
||||
}
|
@ -12,29 +12,13 @@
|
||||
*******************************************************************************/
|
||||
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.List;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.EcoreUtil2;
|
||||
import org.eclipse.xtext.naming.IQualifiedNameConverter;
|
||||
|
||||
import com._1c.g5.v8.dt.bsl.common.IBslPreferences;
|
||||
import com._1c.g5.v8.dt.bsl.model.DynamicFeatureAccess;
|
||||
import com._1c.g5.v8.dt.bsl.model.FeatureEntry;
|
||||
import com._1c.g5.v8.dt.bsl.model.util.BslUtil;
|
||||
import com._1c.g5.v8.dt.core.platform.IResourceLookup;
|
||||
import com._1c.g5.v8.dt.mcore.Environmental;
|
||||
import com._1c.g5.v8.dt.mcore.util.Environments;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -43,7 +27,7 @@ import com.google.inject.Inject;
|
||||
* @author Dmitriy Marmyshev
|
||||
*/
|
||||
public class DynamicFeatureAccessMethodNotFoundCheck
|
||||
extends AbstractTypeCheck
|
||||
extends AbstractDynamicFeatureAccessTypeCheck
|
||||
{
|
||||
|
||||
private static final String CHECK_ID = "dynamic-access-method-not-found"; //$NON-NLS-1$
|
||||
@ -69,60 +53,28 @@ public class DynamicFeatureAccessMethodNotFoundCheck
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureCheck(CheckConfigurer builder)
|
||||
protected String getTitle()
|
||||
{
|
||||
builder.title(Messages.DynamicFeatureAccessMethodNotFoundCheck_title)
|
||||
.description(Messages.DynamicFeatureAccessMethodNotFoundCheck_description)
|
||||
.complexity(CheckComplexity.NORMAL)
|
||||
.severity(IssueSeverity.MAJOR)
|
||||
.issueType(IssueType.CODE_STYLE)
|
||||
.extension(new ModuleTopObjectNameFilterExtension())
|
||||
.extension(new StrictTypeAnnotationCheckExtension())
|
||||
.module()
|
||||
.checkedObjectType(DYNAMIC_FEATURE_ACCESS);
|
||||
|
||||
return Messages.DynamicFeatureAccessMethodNotFoundCheck_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
|
||||
IProgressMonitor monitor)
|
||||
protected String getDescription()
|
||||
{
|
||||
if (monitor.isCanceled() || !(object instanceof EObject))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DynamicFeatureAccess fa = (DynamicFeatureAccess)object;
|
||||
if (fa.getName() == null || fa.getName().isBlank())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isMethod = BslUtil.getInvocation(fa) != null;
|
||||
if (isMethod && isEmptySource(fa))
|
||||
{
|
||||
String message = MessageFormat
|
||||
.format(Messages.DynamicFeatureAccessTypeCheck_Method_M_not_found_in_accessed_object, fa.getName());
|
||||
|
||||
resultAceptor.addIssue(message, FEATURE_ACCESS__NAME);
|
||||
}
|
||||
|
||||
return Messages.DynamicFeatureAccessMethodNotFoundCheck_description;
|
||||
}
|
||||
|
||||
private boolean isEmptySource(DynamicFeatureAccess object)
|
||||
@Override
|
||||
protected boolean isCheckDfaMethod()
|
||||
{
|
||||
Environmental envs = EcoreUtil2.getContainerOfType(object, Environmental.class);
|
||||
if (envs == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Environments actualEnvs = bslPreferences.getLoadEnvs(object).intersect(envs.environments());
|
||||
if (actualEnvs.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
List<FeatureEntry> objects = dynamicFeatureAccessComputer.getLastObject(object, actualEnvs);
|
||||
return objects.isEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getErrorMessage(DynamicFeatureAccess fa)
|
||||
{
|
||||
return MessageFormat.format(Messages.DynamicFeatureAccessTypeCheck_Method_M_not_found_in_accessed_object,
|
||||
fa.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,25 +12,13 @@
|
||||
*******************************************************************************/
|
||||
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 org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.naming.IQualifiedNameConverter;
|
||||
|
||||
import com._1c.g5.v8.dt.bsl.common.IBslPreferences;
|
||||
import com._1c.g5.v8.dt.bsl.model.DynamicFeatureAccess;
|
||||
import com._1c.g5.v8.dt.bsl.model.FeatureAccess;
|
||||
import com._1c.g5.v8.dt.bsl.model.util.BslUtil;
|
||||
import com._1c.g5.v8.dt.core.platform.IResourceLookup;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -39,7 +27,7 @@ import com.google.inject.Inject;
|
||||
* @author Dmitriy Marmyshev
|
||||
*/
|
||||
public class DynamicFeatureAccessTypeCheck
|
||||
extends AbstractTypeCheck
|
||||
extends AbstractDynamicFeatureAccessTypeCheck
|
||||
{
|
||||
private static final String CHECK_ID = "property-return-type"; //$NON-NLS-1$
|
||||
|
||||
@ -64,41 +52,28 @@ public class DynamicFeatureAccessTypeCheck
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureCheck(CheckConfigurer builder)
|
||||
protected String getTitle()
|
||||
{
|
||||
builder.title(Messages.DynamicFeatureAccessTypeCheck_title)
|
||||
.description(Messages.DynamicFeatureAccessTypeCheck_description)
|
||||
.complexity(CheckComplexity.NORMAL)
|
||||
.severity(IssueSeverity.MAJOR)
|
||||
.issueType(IssueType.CODE_STYLE)
|
||||
.extension(new ModuleTopObjectNameFilterExtension())
|
||||
.extension(new StrictTypeAnnotationCheckExtension())
|
||||
.module()
|
||||
.checkedObjectType(DYNAMIC_FEATURE_ACCESS);
|
||||
return Messages.DynamicFeatureAccessTypeCheck_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
|
||||
IProgressMonitor monitor)
|
||||
protected String getDescription()
|
||||
{
|
||||
if (monitor.isCanceled() || !(object instanceof EObject))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return Messages.DynamicFeatureAccessTypeCheck_description;
|
||||
}
|
||||
|
||||
FeatureAccess fa = (FeatureAccess)object;
|
||||
if (fa.getName() == null || fa.getName().isBlank())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
protected boolean isCheckDfaMethod()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isMethod = BslUtil.getInvocation(fa) != null;
|
||||
if (!isMethod && isEmptyTypes((EObject)object))
|
||||
{
|
||||
String message = MessageFormat
|
||||
.format(Messages.DynamicFeatureAccessTypeCheck_Feature_access_M_has_no_return_type, fa.getName());
|
||||
resultAceptor.addIssue(message, FEATURE_ACCESS__NAME);
|
||||
}
|
||||
@Override
|
||||
protected String getErrorMessage(DynamicFeatureAccess fa)
|
||||
{
|
||||
return MessageFormat.format(Messages.DynamicFeatureAccessTypeCheck_Feature_access_M_has_no_return_type,
|
||||
fa.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ final class Messages
|
||||
extends NLS
|
||||
{
|
||||
private static final String BUNDLE_NAME = "com.e1c.v8codestyle.bsl.strict.check.messages"; //$NON-NLS-1$
|
||||
public static String AbstractDynamicFeatureAccessTypeCheck_Skip_source_object_types;
|
||||
public static String DocCommentFieldTypeCheck_description;
|
||||
public static String DocCommentFieldTypeCheck_Field__N__has_no_type_definition;
|
||||
public static String DocCommentFieldTypeCheck_title;
|
||||
|
@ -12,6 +12,8 @@
|
||||
# 1C-Soft LLC - initial API and implementation
|
||||
###############################################################################
|
||||
|
||||
AbstractDynamicFeatureAccessTypeCheck_Skip_source_object_types = Skip source object types if object not found, comma-separated
|
||||
|
||||
DocCommentFieldTypeCheck_Field__N__has_no_type_definition = Field "{0}" has no type definition
|
||||
|
||||
DocCommentFieldTypeCheck_description = Check of module strict types system that documentation comment field has section with types
|
||||
|
@ -12,6 +12,8 @@
|
||||
# 1C-Soft LLC - initial API and implementation
|
||||
###############################################################################
|
||||
|
||||
AbstractDynamicFeatureAccessTypeCheck_Skip_source_object_types = Если объект не найден, пропускать типы объекта источника, через запятую
|
||||
|
||||
DocCommentFieldTypeCheck_Field__N__has_no_type_definition = Поле "{0}" не имеет описания типа
|
||||
|
||||
DocCommentFieldTypeCheck_description = Система строгой типизации кода проверяет что поле документирующего комментария имеет описание типа
|
||||
|
Loading…
Reference in New Issue
Block a user