1
0
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:
Dmitriy Marmyshev 2022-02-12 17:07:34 +03:00
parent 38e5daf702
commit 59691afe7a
7 changed files with 227 additions and 105 deletions

View File

@ -49,6 +49,7 @@
- Исправлен идентификатор проверки тип в строгой типизации: `doc-comment-field-type` -> `doc-comment-field-type-strict`
- Ограничения на использование экспортных процедур и функций в модулях команд и форм
- Вызов "Заблокировать()" находится вне попытки
- Для проверок dynamic-access-method-not-found и property-return-type добавлена возможность исключения по типам (COM-Объекты)
#### Запросы

View File

@ -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)));
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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;

View File

@ -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

View File

@ -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 = Система строгой типизации кода проверяет что поле документирующего комментария имеет описание типа