Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
* Copyright (C) 2025, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -12,7 +12,7 @@
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;

import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.SIMPLE_STATEMENT;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.MODULE;

import java.text.MessageFormat;
import java.util.HashMap;
Expand All @@ -23,21 +23,25 @@
import java.util.TreeSet;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.EcoreUtil2;

import com._1c.g5.v8.dt.bsl.contextdef.IBslModuleContextDefService;
import com._1c.g5.v8.dt.bsl.model.BinaryExpression;
import com._1c.g5.v8.dt.bsl.model.BinaryOperation;
import com._1c.g5.v8.dt.bsl.model.BooleanLiteral;
import com._1c.g5.v8.dt.bsl.model.Conditional;
import com._1c.g5.v8.dt.bsl.model.EmptyStatement;
import com._1c.g5.v8.dt.bsl.model.Expression;
import com._1c.g5.v8.dt.bsl.model.FormalParam;
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.ModuleType;
import com._1c.g5.v8.dt.bsl.model.SimpleStatement;
import com._1c.g5.v8.dt.bsl.model.Statement;
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
import com._1c.g5.v8.dt.bsl.resource.BslEventsService;
import com._1c.g5.v8.dt.common.Pair;
import com._1c.g5.v8.dt.form.model.FormExtInfo;
import com._1c.g5.v8.dt.lcore.util.CaseInsensitiveString;
import com._1c.g5.v8.dt.mcore.Event;
Expand All @@ -49,7 +53,6 @@
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.BasicCheck;
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.e1c.v8codestyle.check.StandardCheckExtension;
Expand All @@ -63,7 +66,7 @@
* @author Victor Golubev
*/
public class EventHandlerBooleanParamCheck
extends BasicCheck
extends AbstractModuleStructureCheck
{
private static final String DELIMITER = ","; //$NON-NLS-1$

Expand Down Expand Up @@ -117,7 +120,7 @@ protected void configureCheck(CheckConfigurer builder)
.issueType(IssueType.WARNING)
.extension(new StandardCheckExtension(686, getCheckId(), BslPlugin.PLUGIN_ID))
.module()
.checkedObjectType(SIMPLE_STATEMENT)
.checkedObjectType(MODULE)
.parameter(PARAM_CHECK_EVENT_ONLY, Boolean.class, DEFAULT_CHECK_EVENT_ONLY,
Messages.EventHandlerBooleanParamCheck_Check_only_in_event_handlers)
.parameter(PARAM_PARAMS_TO_TRUE, String.class, String.join(DELIMITER, DEFAULT_PARAMS_TO_TRUE),
Expand All @@ -130,9 +133,83 @@ protected void configureCheck(CheckConfigurer builder)
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor)
{
SimpleStatement statement = (SimpleStatement)object;
Expression left = statement.getLeft();
Expression right = statement.getRight();
Module module = (Module)object;
if (module == null)
{
return;
}
Map<CaseInsensitiveString, List<EObject>> eventHandlersMod = bslEventsService.getEventHandlers(module);
Map<CaseInsensitiveString, List<EObject>> eventHandlersContainerMod =
bslEventsService.getEventHandlersContainer(module);
Map<CaseInsensitiveString, Event> eventHandlers = getAllModuleEvents(module);
boolean checkEventOnly = parameters.getBoolean(PARAM_CHECK_EVENT_ONLY);
for (Method method : module.allMethods())
{
Pair<Event, Integer> eventWithParamIndex =
getActualEvent(eventHandlersMod, eventHandlersContainerMod, eventHandlers, module, method);
if (eventWithParamIndex.first == null && checkEventOnly)
{
continue;
}
EList<Statement> statements = method.allStatements();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EventHandlerBooleanParamCheck.java
вот, погляди, пожалуйста, оставил твою идею, но попытался еще ее чуть улучшить - не вытаскивать SimpleStatement из тех методов, которые не события, если проверяем по умолчанию только для событий.

if (statements == null)
{
continue;
}
for (EObject statement : statements)
{
if (statement instanceof EmptyStatement)
{
continue;
}
else if (statement instanceof SimpleStatement)
{
checkSimpleStatement(statement, resultAceptor, parameters, monitor, module, method,
eventWithParamIndex);
}
else if (statement instanceof Statement)
{
checkStatement(statement, resultAceptor, parameters, monitor, module, method, eventWithParamIndex);
}
}
}
}

private void checkStatement(EObject statement, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor, Module module, Method method, Pair<Event, Integer> eventWithParamIndex)
{
if (statement instanceof SimpleStatement)
{
checkSimpleStatement(statement, resultAceptor, parameters, monitor, module, method, eventWithParamIndex);
}
else if (statement instanceof EmptyStatement)
{
return;
}
else if (statement instanceof Conditional || statement instanceof Statement)
{
EList<EObject> listStatement = statement.eContents();
if (listStatement == null)
{
return;
}
for (EObject eObject : listStatement)
{
if (eObject instanceof EmptyStatement)
{
continue;
}
checkStatement(eObject, resultAceptor, parameters, monitor, module, method, eventWithParamIndex);
}
}
}

private void checkSimpleStatement(EObject statement, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor, Module module, Method method, Pair<Event, Integer> eventWithParamIndex)
{
SimpleStatement simpleStatement = (SimpleStatement)statement;
Expression left = simpleStatement.getLeft();
Expression right = simpleStatement.getRight();
if (!(left instanceof StaticFeatureAccess))
{
return;
Expand All @@ -149,9 +226,7 @@ protected void check(Object object, ResultAcceptor resultAceptor, ICheckParamete
{
return;
}

FormalParam param = (FormalParam)stat.getFeatureEntries().get(0).getFeature();

// Fast check by name and boolean literal
if (right instanceof BooleanLiteral
&& (paramsToTrue.contains(param.getName()) && ((BooleanLiteral)right).isIsTrue()
Expand All @@ -161,8 +236,7 @@ protected void check(Object object, ResultAcceptor resultAceptor, ICheckParamete
}

boolean valueToCheckAssignment = paramsToTrue.contains(paramName);
Parameter eventParameter = getEventBooleanParameter(param, monitor);

Parameter eventParameter = getEventBooleanParameter(param, monitor, module, method, eventWithParamIndex);
if (eventParameter != null)
{
if (paramsToTrue.contains(eventParameter.getNameRu()) || paramsToTrue.contains(eventParameter.getName()))
Expand All @@ -189,7 +263,6 @@ else if (checkEventOnly || !paramsToTrue.contains(paramName) && !paramsToFalse.c
{
return;
}

// check right expression
if (!isCorrectBooleanExpression(right, paramName, valueToCheckAssignment, monitor))
{
Expand All @@ -208,46 +281,68 @@ else if (checkEventOnly || !paramsToTrue.contains(paramName) && !paramsToFalse.c
}
}

private Parameter getEventBooleanParameter(FormalParam param, IProgressMonitor monitor)
private Parameter getEventBooleanParameter(FormalParam param, IProgressMonitor monitor, Module module,
Method method, Pair<Event, Integer> eventWithParamIndex)
{
Method method = EcoreUtil2.getContainerOfType(param, Method.class);

if (monitor.isCanceled() || method == null || method.getFormalParams().isEmpty())
{
return null;
}

Module module = EcoreUtil2.getContainerOfType(method, Module.class);
if (monitor.isCanceled() || !isCorrectModule(module))
{
return null;
}

List<FormalParam> params = method.getFormalParams();
int index = params.indexOf(param);

Map<CaseInsensitiveString, Event> eventHandlers = getAllModuleEvents(module);
String name = method.getName();
if (name == null)
if (method.getName() == null)
{
return null;
}
if (monitor.isCanceled() || eventWithParamIndex.first == null
|| eventWithParamIndex.first.getParamSet().isEmpty())
{
return null;
}
CaseInsensitiveString methodName = new CaseInsensitiveString(name);

// get actual parameter name in case it renamed, but still boolean
ParamSet paramSet = eventWithParamIndex.first.actualParamSet(method.getFormalParams().size());
int index = method.getFormalParams().indexOf(param);
index += index > 0 ? eventWithParamIndex.second : 0;
if (paramSet != null)
{
List<Parameter> eventParameters = paramSet.getParams();
if (index < eventParameters.size())
{
Parameter eventParameter = eventParameters.get(index);
if (isBooleanParameter(eventParameter))
{
return eventParameter;
}
}
}
return null;
}

private Pair<Event, Integer> getActualEvent(Map<CaseInsensitiveString, List<EObject>> eventHandlersMod,
Map<CaseInsensitiveString, List<EObject>> eventHandlersContainerMod,
Map<CaseInsensitiveString, Event> eventHandlers, Module module, Method method)
{
int diff = 0;
CaseInsensitiveString methodName = new CaseInsensitiveString(method.getName());
Event event = eventHandlers.get(methodName);
if (event == null && isCorrectModuleForCustomHandlers(module))
{
// Get event for Form Item event handlers or common module event subscription
List<EObject> enventHandlers = bslEventsService.getEventHandlers(module).get(methodName);
List<EObject> enventHandlers = eventHandlersMod.get(methodName);
if (enventHandlers != null && !enventHandlers.isEmpty())
{
if (index > 0)
List<EObject> containers = eventHandlersContainerMod.get(methodName);
if (containers == null
|| containers.stream().noneMatch(e -> e instanceof AbstractForm || e instanceof FormExtInfo))
{
List<EObject> containers = bslEventsService.getEventHandlersContainer(module).get(methodName);
if (containers == null
|| containers.stream().noneMatch(e -> e instanceof AbstractForm || e instanceof FormExtInfo))
{
// shift because Form Item (or event subscription) Event doesn't contains first parameter "Item"
--index;
}
// shift because Form Item (or event subscription) Event doesn't contains first parameter "Item"
diff = -1;
}

for (EObject handler : enventHandlers)
Expand All @@ -260,26 +355,7 @@ private Parameter getEventBooleanParameter(FormalParam param, IProgressMonitor m
}
}
}
if (monitor.isCanceled() || event == null || event.getParamSet().isEmpty())
{
return null;
}

// get actual parameter name in case it renamed, but still boolean
ParamSet paramSet = event.actualParamSet(params.size());
if (paramSet != null)
{
List<Parameter> eventParameters = paramSet.getParams();
if (index < eventParameters.size())
{
Parameter eventParameter = eventParameters.get(index);
if (isBooleanParameter(eventParameter))
{
return eventParameter;
}
}
}
return null;
return Pair.newPair(event, diff);
}

private boolean isCorrectBooleanExpression(Expression expr, String paramName, boolean checkState,
Expand Down Expand Up @@ -319,7 +395,6 @@ private boolean isCorrectBooleanExpression(BinaryExpression expr, String paramNa
{
operation = BinaryOperation.OR;
}

else
{
operation = BinaryOperation.AND;
Expand Down Expand Up @@ -366,7 +441,6 @@ private Set<String> getParamsToTrue(ICheckParameters parameters)

private Map<CaseInsensitiveString, Event> getAllModuleEvents(Module module)
{

Map<CaseInsensitiveString, Event> result = new HashMap<>();
if (module.getModuleType() == ModuleType.FORM_MODULE)
{
Expand Down
Loading