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

#1 Перенос проверок из EDT (#886)

This commit is contained in:
Dmitriy Marmyshev 2021-12-24 10:16:26 +02:00 committed by GitHub
parent 1f4c291075
commit 4348dd1911
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 826 additions and 1 deletions

View File

@ -20,6 +20,7 @@ Import-Package: com._1c.g5.v8.bm.core;version="[7.0.0,8.0.0)",
com._1c.g5.v8.dt.bsl.contextdef;version="[2.0.0,3.0.0)",
com._1c.g5.v8.dt.bsl.documentation.comment;version="[3.0.0,4.0.0)",
com._1c.g5.v8.dt.bsl.model;version="[5.0.0,6.0.0)",
com._1c.g5.v8.dt.bsl.model.resource.owner;version="[2.0.0,3.0.0)",
com._1c.g5.v8.dt.bsl.model.util;version="[4.0.0,5.0.0)",
com._1c.g5.v8.dt.bsl.resource;version="[13.0.0,14.0.0)",
com._1c.g5.v8.dt.bsl.typesystem;version="[9.0.0,10.0.0)",

View File

@ -140,6 +140,18 @@
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleStructureTopRegionCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleEmptyMethodCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleUnusedLocalVariableCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ModuleUnusedMethodCheck">
</check>
</extension>
<extension

View File

@ -75,6 +75,22 @@ final class Messages
public static String ModuleStructureTopRegionCheck_title;
public static String ModuleUnusedMethodCheck_Title;
public static String ModuleUnusedMethodCheck_Description;
public static String ModuleUnusedMethodCheck_Exclude_method_name_pattern_title;
public static String ModuleUnusedMethodCheck_Unused_method__0;
public static String ModuleEmptyMethodCheck_Title;
public static String ModuleEmptyMethodCheck_Description;
public static String ModuleEmptyMethodCheck_Exclude_method_name_pattern_title;
public static String ModuleEmptyMethodCheck_Allow_method_comments_title;
public static String ModuleEmptyMethodCheck_Empty_method__0;
public static String ModuleUnusedLocalVariableCheck_Title;
public static String ModuleUnusedLocalVariableCheck_Description;
public static String ModuleUnusedLocalVariableCheck_Unused_local_variable__0;
public static String ModuleUnusedLocalVariableCheck_Probably_variable_not_initilized_yet__0;
public static String QueryInLoop_check_query_in_infinite_loop;
public static String QueryInLoop_description;
public static String QueryInLoop_Loop_has_method_with_query__0;

View File

@ -0,0 +1,132 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.METHOD;
import java.text.MessageFormat;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import com._1c.g5.v8.dt.bsl.documentation.comment.BslCommentUtils;
import com._1c.g5.v8.dt.bsl.model.EmptyStatement;
import com._1c.g5.v8.dt.bsl.model.Method;
import com._1c.g5.v8.dt.bsl.model.Statement;
import com._1c.g5.v8.dt.common.StringUtils;
import com._1c.g5.v8.dt.mcore.McorePackage;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.BasicCheck;
import com.e1c.g5.v8.dt.check.components.ModuleTopObjectNameFilterExtension;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.google.common.collect.Lists;
/**
* Empty module method check.
*
* @author Andrey Volkov
*/
public final class ModuleEmptyMethodCheck
extends BasicCheck
{
private static final String CHECK_ID = "module-empty-method"; //$NON-NLS-1$
private static final String EXCLUDE_METHOD_NAME_PATTERN_PARAMETER_NAME = "excludeModuleMethodNamePattern"; //$NON-NLS-1$
private static final String ALLOW_METHOD_COMMENTS_PARAMETER_NAME = "allowMethodComments"; //$NON-NLS-1$
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.ModuleEmptyMethodCheck_Title)
.description(Messages.ModuleEmptyMethodCheck_Description)
.extension(new ModuleTopObjectNameFilterExtension())
.parameter(EXCLUDE_METHOD_NAME_PATTERN_PARAMETER_NAME, String.class, StringUtils.EMPTY,
Messages.ModuleEmptyMethodCheck_Exclude_method_name_pattern_title)
.parameter(ALLOW_METHOD_COMMENTS_PARAMETER_NAME, Boolean.class, Boolean.TRUE.toString(),
Messages.ModuleEmptyMethodCheck_Allow_method_comments_title)
.issueType(IssueType.WARNING)
.module()
.checkedObjectType(METHOD);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor progressMonitor)
{
Method method = (Method)object;
String methodName = method.getName();
String excludeNamePattern = parameters.getString(EXCLUDE_METHOD_NAME_PATTERN_PARAMETER_NAME);
boolean allowMethodComments = parameters.getBoolean(ALLOW_METHOD_COMMENTS_PARAMETER_NAME);
if (!isExcludeName(methodName, excludeNamePattern) && isEmpty(method, allowMethodComments))
{
resultAceptor.addIssue(MessageFormat.format(Messages.ModuleEmptyMethodCheck_Empty_method__0, methodName),
method, McorePackage.Literals.NAMED_ELEMENT__NAME);
}
}
private boolean isEmpty(Method method, boolean allowMethodComments)
{
if (method.allStatements().isEmpty())
{
return !allowMethodComments || isMethodHasNoComment(method);
}
for (Statement statement : method.allStatements())
{
if (!(statement instanceof EmptyStatement))
{
return false;
}
}
return true;
}
private boolean isMethodHasNoComment(Method method)
{
INode node = NodeModelUtils.findActualNodeFor(method);
if (node != null)
{
List<ILeafNode> allLeafNode = Lists.newArrayList(node.getLeafNodes());
for (int i = allLeafNode.size() - 1; i >= 0; --i)
{
ILeafNode leafNode = allLeafNode.get(i);
if (leafNode.getOffset() < node.getOffset())
{
break;
}
if (BslCommentUtils.isCommentNode(leafNode))
{
return false;
}
}
}
return true;
}
private boolean isExcludeName(String name, String excludeNamePattern)
{
return StringUtils.isNotEmpty(excludeNamePattern) && name.matches(excludeNamePattern);
}
}

View File

@ -0,0 +1,282 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.MODULE;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import com._1c.g5.v8.dt.bsl.common.VariableProcessor;
import com._1c.g5.v8.dt.bsl.model.Block;
import com._1c.g5.v8.dt.bsl.model.BslPackage;
import com._1c.g5.v8.dt.bsl.model.DeclareStatement;
import com._1c.g5.v8.dt.bsl.model.ExplicitVariable;
import com._1c.g5.v8.dt.bsl.model.ForToStatement;
import com._1c.g5.v8.dt.bsl.model.FormalParam;
import com._1c.g5.v8.dt.bsl.model.ImplicitVariable;
import com._1c.g5.v8.dt.bsl.model.Method;
import com._1c.g5.v8.dt.bsl.model.Module;
import com._1c.g5.v8.dt.bsl.model.SimpleStatement;
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
import com._1c.g5.v8.dt.bsl.model.Variable;
import com._1c.g5.v8.dt.bsl.model.resource.owner.IBslOwnerComputerService;
import com._1c.g5.v8.dt.bsl.resource.BslResource;
import com._1c.g5.v8.dt.bsl.resource.DynamicFeatureAccessComputer;
import com._1c.g5.v8.dt.bsl.typesystem.util.TypeSystemUtil;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.BasicCheck;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.google.common.collect.Lists;
/**
* Unused module local variable check.
*
* @author Andrey Volkov
*/
public final class ModuleUnusedLocalVariableCheck
extends BasicCheck
{
private static final String CHECK_ID = "module-unused-local-variable"; //$NON-NLS-1$
private final DynamicFeatureAccessComputer dynamicComputer;
private final IBslOwnerComputerService ownerService;
/**
* Instantiates a new module unused local variable check.
*/
public ModuleUnusedLocalVariableCheck()
{
super();
IResourceServiceProvider serviceProvider =
IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(URI.createURI("*.bsl")); //$NON-NLS-1$
dynamicComputer = serviceProvider.get(DynamicFeatureAccessComputer.class);
ownerService = serviceProvider.get(IBslOwnerComputerService.class);
}
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.ModuleUnusedLocalVariableCheck_Title)
.description(Messages.ModuleUnusedLocalVariableCheck_Description)
.issueType(IssueType.WARNING)
.module()
.checkedObjectType(MODULE);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor progressMonitor)
{
Module module = (Module)object;
VariableProcessor processor = new VariableProcessor(module.allStatements(), dynamicComputer);
processor.process();
Map<Variable, List<INode>> variablesChangeValueModule = processor.variablesForChangeValue();
Map<Variable, List<INode>> variablesForReadValueModule = processor.variablesForReadValue();
for (Method method : getProcessMethods(module))
{
processor = new VariableProcessor(method.allStatements(), dynamicComputer);
processor.process();
Map<Variable, List<INode>> variablesChangeValue = processor.variablesForChangeValue();
Map<Variable, List<INode>> variablesForReadValue = processor.variablesForReadValue();
for (Map.Entry<Variable, List<INode>> variable : variablesChangeValue.entrySet())
{
if (variable.getKey() instanceof FormalParam)
{
continue;
}
Block actualVariableBlock = EcoreUtil2.getContainerOfType(variable.getKey(), Block.class);
if (actualVariableBlock != method)
{
continue;
}
if (variable.getKey() instanceof ExplicitVariable && ((ExplicitVariable)variable.getKey()).isExport())
{
continue;
}
if (variable.getKey() instanceof ImplicitVariable)
{
ImplicitVariable implicitVariable = (ImplicitVariable)variable.getKey();
if (implicitVariable.eContainer()
.eContainingFeature() == BslPackage.Literals.FOR_STATEMENT__VARIABLE_ACCESS
&& implicitVariable.eContainer().eContainer() instanceof ForToStatement)
{
continue;
}
if (isUniqueForStaticFeatureAccess(implicitVariable))
{
continue;
}
}
if (actualVariableBlock == module)
{
variablesChangeValueModule.computeIfAbsent(variable.getKey(), item -> Lists.newArrayList())
.addAll(variable.getValue());
}
List<INode> readValueNodes = variablesForReadValue.get(variable.getKey());
if (readValueNodes == null)
{
resultAceptor
.addIssue(MessageFormat.format(Messages.ModuleUnusedLocalVariableCheck_Unused_local_variable__0,
variable.getKey().getName()), variable.getKey());
}
else if (variable.getKey() instanceof ImplicitVariable)
{
ImplicitVariable implicitVariable = (ImplicitVariable)variable.getKey();
EObject variableOwner = implicitVariable.eContainer();
if (variableOwner instanceof StaticFeatureAccess
&& variableOwner.eContainer() instanceof SimpleStatement)
{
for (INode readValueNode : readValueNodes)
{
if (readValueNode.getSemanticElement() == null)
{
continue;
}
if (EcoreUtil2.getContainerOfType(readValueNode.getSemanticElement(),
SimpleStatement.class) == variableOwner.eContainer())
{
resultAceptor.addIssue(MessageFormat.format(
Messages.ModuleUnusedLocalVariableCheck_Probably_variable_not_initilized_yet__0,
implicitVariable.getName()), readValueNode.getSemanticElement());
}
}
}
}
}
for (Map.Entry<Variable, List<INode>> variable : variablesForReadValue.entrySet())
{
Block actualVariableBlock = EcoreUtil2.getContainerOfType(variable.getKey(), Block.class);
if (actualVariableBlock == module)
{
variablesForReadValueModule.computeIfAbsent(variable.getKey(), item -> Lists.newArrayList())
.addAll(variable.getValue());
}
}
for (DeclareStatement decl : method.allDeclareStatements())
{
for (ExplicitVariable variable : decl.getVariables())
{
if (variable.isExport())
{
continue;
}
boolean foundInChange = variablesChangeValue.keySet().contains(variable);
boolean foundInRead = variablesForReadValue.keySet().contains(variable);
if (!foundInChange && !foundInRead)
{
resultAceptor.addIssue(
MessageFormat.format(Messages.ModuleUnusedLocalVariableCheck_Unused_local_variable__0,
variable.getName()),
variable);
}
if (!foundInChange)
{
resultAceptor.addIssue(MessageFormat.format(
Messages.ModuleUnusedLocalVariableCheck_Probably_variable_not_initilized_yet__0,
variable.getName()), variable);
}
if (foundInChange && foundInRead)
{
INode changeValueNode = variablesChangeValue.get(variable).get(0);
INode readValueNode = variablesForReadValue.get(variable).get(0);
if (readValueNode.getOffset() < changeValueNode.getOffset())
{
resultAceptor.addIssue(MessageFormat.format(
Messages.ModuleUnusedLocalVariableCheck_Probably_variable_not_initilized_yet__0,
variable.getName()), readValueNode.getSemanticElement());
}
}
}
}
}
for (Map.Entry<Variable, List<INode>> variable : variablesChangeValueModule.entrySet())
{
if (EcoreUtil2.getContainerOfType(variable.getKey(), Block.class) != module)
{
continue;
}
if (variable.getKey() instanceof ExplicitVariable && ((ExplicitVariable)variable.getKey()).isExport())
{
continue;
}
List<INode> readValueNodes = variablesForReadValueModule.get(variable.getKey());
if (readValueNodes == null && !(variable.getKey() instanceof ImplicitVariable
&& isUniqueForStaticFeatureAccess((ImplicitVariable)variable.getKey())))
{
resultAceptor
.addIssue(MessageFormat.format(Messages.ModuleUnusedLocalVariableCheck_Unused_local_variable__0,
variable.getKey().getName()), variable.getKey());
}
}
}
private List<Method> getProcessMethods(Module module)
{
List<Method> processingObjects;
if (!onlyMethodReparse(module))
{
processingObjects = Lists.newArrayList(module.allMethods());
}
else
{
BslResource resource = (BslResource)module.eResource();
processingObjects = com._1c.g5.v8.dt.bsl.util.BslUtil.getDependMethodsTree(resource.getReparseMethod())
.stream()
.filter(item -> item instanceof Method)
.map(item -> (Method)item)
.collect(Collectors.toList());
processingObjects.add(resource.getReparseMethod());
}
return processingObjects;
}
private boolean onlyMethodReparse(Module module)
{
// TODO - only full validation first, optimization later
//return module.eResource() != null && ((BslResource)module.eResource()).isOnlyMethodReparse()
// && getCheckMode() != BslCancelableDiagnostician.ALL_FOR_FULL_MODULE;
return false;
}
// TODO - only full validation first, optimization later
//private CheckMode getCheckMode()
//{
// return state.get().checkMode;
//}
private boolean isUniqueForStaticFeatureAccess(ImplicitVariable implicitVariable)
{
return implicitVariable.eContainer() instanceof StaticFeatureAccess && !implicitVariable.getEnvironments()
.equals(TypeSystemUtil.getActualEnvironments(implicitVariable.eContainer(), ownerService));
}
}

View File

@ -0,0 +1,135 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.MODULE;
import java.text.MessageFormat;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.builder.MonitorBasedCancelIndicator;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.IResourceDescription;
import com._1c.g5.v8.dt.bsl.common.IModuleExtensionService;
import com._1c.g5.v8.dt.bsl.common.IModuleExtensionServiceProvider;
import com._1c.g5.v8.dt.bsl.model.Method;
import com._1c.g5.v8.dt.bsl.model.Module;
import com._1c.g5.v8.dt.bsl.resource.BslResourceDescription;
import com._1c.g5.v8.dt.common.StringUtils;
import com._1c.g5.v8.dt.mcore.McorePackage;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.BasicCheck;
import com.e1c.g5.v8.dt.check.components.ModuleTopObjectNameFilterExtension;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
/**
* Unused module method check. This class needs {@link IQualifiedNameProvider} to inject other service.
*
* @author Andrey Volkov
* @author Dmitriy Marmyshev
*/
public final class ModuleUnusedMethodCheck
extends BasicCheck
{
private static final String CHECK_ID = "module-unused-method"; //$NON-NLS-1$
private static final String EXCLUDE_METHOD_NAME_PATTERN_PARAMETER_NAME = "excludeModuleMethodNamePattern"; //$NON-NLS-1$
private final IResourceDescription.Manager resourceDescriptionManager;
/**
* Instantiates a new module unused method check.
*
* @param resourceDescriptionManager the resource description manager service, cannot be {@code null}.
*/
@Inject
public ModuleUnusedMethodCheck(IResourceDescription.Manager resourceDescriptionManager)
{
super();
this.resourceDescriptionManager = resourceDescriptionManager;
}
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.ModuleUnusedMethodCheck_Title)
.description(Messages.ModuleUnusedMethodCheck_Description)
.extension(new ModuleTopObjectNameFilterExtension())
.parameter(EXCLUDE_METHOD_NAME_PATTERN_PARAMETER_NAME, String.class, StringUtils.EMPTY,
Messages.ModuleUnusedMethodCheck_Exclude_method_name_pattern_title)
.issueType(IssueType.WARNING)
.module()
.checkedObjectType(MODULE);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor progressMonitor)
{
Module module = (Module)object;
IModuleExtensionService service = IModuleExtensionServiceProvider.INSTANCE.getModuleExtensionService();
String excludeNamePattern = parameters.getString(EXCLUDE_METHOD_NAME_PATTERN_PARAMETER_NAME);
Predicate<? super Method> predicate = method -> !method.isUsed() && !method.isExport() && !method.isEvent()
&& service.getSourceMethodNames(method).isEmpty() && !isExcludeName(method.getName(), excludeNamePattern);
// TODO - only full validation first, optimization later
//@formatter:off
//if (!((BslResource)module.eResource()).isOnlyMethodReparse())
//{
Set<URI> usedMethods = getUsedMethods(progressMonitor, module.eResource());
predicate = predicate.and(method -> !usedMethods.contains(EcoreUtil.getURI((EObject)method)));
//}
//@formatter:on
module.allMethods()
.stream()
.filter(predicate)
.forEach(unusedMethod -> resultAceptor.addIssue(
MessageFormat.format(Messages.ModuleUnusedMethodCheck_Unused_method__0, unusedMethod.getName()),
unusedMethod, McorePackage.Literals.NAMED_ELEMENT__NAME));
}
private Set<URI> getUsedMethods(IProgressMonitor progressMonitor, Resource resource)
{
IResourceDescription descr = resourceDescriptionManager.getResourceDescription(resource);
return (descr instanceof BslResourceDescription
? Lists.newArrayList(((BslResourceDescription)descr)
.getReferenceDescriptions(new MonitorBasedCancelIndicator(progressMonitor)))
: Lists.newArrayList(descr.getReferenceDescriptions())).stream()
.map(reference -> reference.getTargetEObjectUri())
.collect(Collectors.toSet());
}
private boolean isExcludeName(String name, String excludeNamePattern)
{
return StringUtils.isNotEmpty(excludeNamePattern) && name.matches(excludeNamePattern);
}
}

View File

@ -94,12 +94,38 @@ MethodTooManyPramsCheck_description = Method has to many parameters
MethodTooManyPramsCheck_title = Method has to many parameters
ModuleEmptyMethodCheck_Allow_method_comments_title = Allow method comments
ModuleEmptyMethodCheck_Description = Empty module method check
ModuleEmptyMethodCheck_Empty_method__0 = Empty method "{0}"
ModuleEmptyMethodCheck_Exclude_method_name_pattern_title = Exclude method name pattern
ModuleEmptyMethodCheck_Title = Empty method check
ModuleStructureTopRegionCheck_description = Check that module structure region is on top
ModuleStructureTopRegionCheck_error_message = Module structure region is not on top
ModuleStructureTopRegionCheck_title = Module structure top region
ModuleUnusedLocalVariableCheck_Description = Unused module local variable check
ModuleUnusedLocalVariableCheck_Probably_variable_not_initilized_yet__0 = Probably local variable "{0}" has not been initiliazed yet
ModuleUnusedLocalVariableCheck_Title = Unused local variable check
ModuleUnusedLocalVariableCheck_Unused_local_variable__0 = Unused local variable "{0}"
ModuleUnusedMethodCheck_Description = Unused module method check
ModuleUnusedMethodCheck_Exclude_method_name_pattern_title = Exclude method name pattern
ModuleUnusedMethodCheck_Title = Unused method check
ModuleUnusedMethodCheck_Unused_method__0 = Unused method "{0}"
NotifyDescriptionToServerProcedureCheck_Notify_description_procedure_should_be_export = Notify description procedure should exist and be export
NotifyDescriptionToServerProcedureCheck_Notify_description_to_Server_procedure = Notify description to Server procedure

View File

@ -94,12 +94,38 @@ MethodTooManyPramsCheck_description = Метод содержит слишком
MethodTooManyPramsCheck_title = Метод содержит слишком много параметров
ModuleEmptyMethodCheck_Allow_method_comments_title = Учитывать комментарии метода
ModuleEmptyMethodCheck_Description = Проверка модуля на наличие пустых методов
ModuleEmptyMethodCheck_Empty_method__0 = Пустой метод "{0}"
ModuleEmptyMethodCheck_Exclude_method_name_pattern_title = Шаблон исключаемых имен методов
ModuleEmptyMethodCheck_Title = Проверка пустых методов
ModuleStructureTopRegionCheck_description = Проверяет что стандартная область структуры модуля не является вложенной
ModuleStructureTopRegionCheck_error_message = Стандартная область структуры модуля является вложенной
ModuleStructureTopRegionCheck_title = Стандартная область структуры модуля верхнеуровневая
ModuleUnusedLocalVariableCheck_Description = Проверка модуля на наличие неиспользуемых локальных переменных
ModuleUnusedLocalVariableCheck_Probably_variable_not_initilized_yet__0 = Возможно, переменная ''{0}'' еще не была проинициализирована
ModuleUnusedLocalVariableCheck_Title = Проверка неиспользуемых локальных переменных
ModuleUnusedLocalVariableCheck_Unused_local_variable__0 = Неиспользуемая локальная переменная ''{0}''
ModuleUnusedMethodCheck_Description = Проверка модуля на наличие неиспользуемых методов
ModuleUnusedMethodCheck_Exclude_method_name_pattern_title = Шаблон исключаемых имен методов
ModuleUnusedMethodCheck_Title = Проверка неиспользуемых методов
ModuleUnusedMethodCheck_Unused_method__0 = Неиспользуемый метод "{0}"
NotifyDescriptionToServerProcedureCheck_Notify_description_procedure_should_be_export = Процедура описания оповещения должна существовать и быть экспортной
NotifyDescriptionToServerProcedureCheck_Notify_description_to_Server_procedure = Описание оповещения на серверную процедуру

View File

@ -15,6 +15,7 @@ package com.e1c.v8codestyle.internal.bsl;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import com._1c.g5.v8.dt.bsl.common.IBslPreferences;
import com._1c.g5.v8.dt.bsl.contextdef.IBslModuleContextDefService;
@ -47,6 +48,7 @@ class ExternalDependenciesModule
bind(IBslPreferences.class).toService();
bind(IQualifiedNameConverter.class).toService();
bind(IBslModuleContextDefService.class).toService();
bind(IQualifiedNameProvider.class).toService();
}
}

View File

@ -0,0 +1,8 @@
Procedure BeforeExit(Cancel, WarningText)
i = 0;
i = i + 1;
EndProcedure
Procedure ModuleEmptyMethodCheck()
EndProcedure

View File

@ -0,0 +1,11 @@
Procedure BeforeExit(Cancel, WarningText)
ModuleUnusedMethodCheck();
EndProcedure
Procedure ModuleUnusedMethodCheck()
i = 0;
EndProcedure

View File

@ -0,0 +1,9 @@
Procedure BeforeExit(Cancel, WarningText)
i = 0;
i = i + 1;
EndProcedure
Procedure ModuleUnusedMethodCheck()
i = 0;
i = i + 1;
EndProcedure

View File

@ -253,8 +253,11 @@ public class AbstractSingleModuleTestBase
String chekcId = getCheckId();
assertNotNull(chekcId);
CheckUid id = new CheckUid(chekcId, BslPlugin.PLUGIN_ID);
return markers.stream()
.filter(m -> chekcId.equals(getCheckIdFromMarker(m, getProject())))
.filter(
m -> id.equals(checkRepository.getUidForShortUid(m.getCheckId(), getProject().getWorkspaceProject())))
.collect(Collectors.toList());
}

View File

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.IExtraInfoKeys;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.ModuleEmptyMethodCheck;
/**
* Tests for the {@link ModuleEmptyMethodCheck}
*
* @author Andrey Volkov
* @author Dmitriy Marmyshev
*/
public class ModuleEmptyMethodCheckTest
extends AbstractSingleModuleTestBase
{
public ModuleEmptyMethodCheckTest()
{
super(ModuleEmptyMethodCheck.class);
}
@Test
public void testSingleCheckMarker() throws Exception
{
updateModule(FOLDER_RESOURCE + "module-empty-method.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals("6", marker.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
}

View File

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.IExtraInfoKeys;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.ModuleUnusedLocalVariableCheck;
/**
* Tests for the {@link ModuleUnusedLocalVariableCheck}
*
* @author Andrey Volkov
* @author Dmitriy Marmyshev
*/
public class ModuleUnusedLocalVariableCheckTest
extends AbstractSingleModuleTestBase
{
public ModuleUnusedLocalVariableCheckTest()
{
super(ModuleUnusedLocalVariableCheck.class);
}
@Test
public void testSingleCheckMarker() throws Exception
{
updateModule(FOLDER_RESOURCE + "module-unused-local-variable.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals("9", marker.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
}

View File

@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.IExtraInfoKeys;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.ModuleUnusedMethodCheck;
/**
* Tests for the {@link ModuleUnusedMethodCheck}
*
* @author Andrey Volkov
* @author Dmitriy Marmyshev
*/
public class ModuleUnusedMethodCheckTest
extends AbstractSingleModuleTestBase
{
private static final String CONFIG_MODULE_FILE_NAME = "/src/Configuration/ManagedApplicationModule.bsl";
public ModuleUnusedMethodCheckTest()
{
super(ModuleUnusedMethodCheck.class);
}
@Test
public void testSingleCheckMarker() throws Exception
{
updateModule(FOLDER_RESOURCE + "module-unused-method.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals("6", marker.getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
@Override
protected String getModuleFileName()
{
return CONFIG_MODULE_FILE_NAME;
}
}