1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2024-11-28 09:33:06 +02:00

#878 Испрвление проверки типа локальной переменной

This commit is contained in:
Dmitriy Marmyshev 2022-02-11 00:39:39 +03:00
parent 124e8edf2d
commit 3d8b76216b
6 changed files with 115 additions and 7 deletions

View File

@ -61,6 +61,7 @@
- Отключено создание модуля менеджера при создании перечисления
- Для проверки md-standard-attribute-synonym-empty исправлена регистрация и улучшена точность позиции ошибки
- Исправлен расчета типов возвращаемых значений функций с вызовом сервера
- Испрвление проверки типа локальной переменной в variable-value-type
## 0.1.0

View File

@ -28,6 +28,7 @@ Import-Package: com._1c.g5.ides.ui.texteditor.xtext.embedded;version="[5.0.0,6.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.typesytem;version="[6.0.0,7.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.services;version="[6.0.0,7.0.0)",

View File

@ -26,17 +26,28 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.IScopeProvider;
import com._1c.g5.v8.dt.bsl.common.IBslPreferences;
import com._1c.g5.v8.dt.bsl.documentation.comment.BslMultiLineCommentDocumentationProvider;
import com._1c.g5.v8.dt.bsl.model.BslPackage;
import com._1c.g5.v8.dt.bsl.model.DynamicFeatureAccess;
import com._1c.g5.v8.dt.bsl.model.ExplicitVariable;
import com._1c.g5.v8.dt.bsl.model.FeatureAccess;
import com._1c.g5.v8.dt.bsl.model.ForEachStatement;
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.Invocation;
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.typesytem.TypeSystemMode;
import com._1c.g5.v8.dt.bsl.model.typesytem.VariableTreeTypeState;
import com._1c.g5.v8.dt.bsl.model.typesytem.VariableTreeTypeStateWithSubStates;
import com._1c.g5.v8.dt.bsl.model.typesytem.VariableTypeState;
import com._1c.g5.v8.dt.bsl.resource.DynamicFeatureAccessComputer;
import com._1c.g5.v8.dt.bsl.resource.TypesComputer;
import com._1c.g5.v8.dt.bsl.typesystem.util.TypeSystemUtil;
@ -142,7 +153,7 @@ public abstract class AbstractTypeCheck
}
/**
* Compute types with respect to system enumeration.
* Compute types with respect to system enumeration and variable type state.
*
* @param object the object, cannot be {@code null}.
* @param envs the environments, cannot be {@code null}.
@ -150,6 +161,15 @@ public abstract class AbstractTypeCheck
*/
protected List<TypeItem> computeTypes(EObject object, Environments envs)
{
if (object instanceof Variable && object.eContainer() instanceof FeatureAccess)
{
return getActualTypesForFeatureVariable((Variable)object, object.eContainer(), envs);
}
else if (object instanceof StaticFeatureAccess && ((StaticFeatureAccess)object).getImplicitVariable() != null)
{
return getActualTypesForFeatureVariable(((StaticFeatureAccess)object).getImplicitVariable(), object, envs);
}
List<TypeItem> types = typeComputer.computeTypes(object, envs);
if (types.isEmpty() && object instanceof DynamicFeatureAccess
@ -178,7 +198,6 @@ public abstract class AbstractTypeCheck
}
return types;
}
/**
@ -344,4 +363,71 @@ public abstract class AbstractTypeCheck
}
}
// TODO replace this with utility com._1c.g5.v8.dt.bsl.typesystem.util.TypeSystemUtil after 2022.1
private List<TypeItem> getActualTypesForFeatureVariable(Variable variable, EObject featureObject, Environments envs)
{
SimpleStatement statement = EcoreUtil2.getContainerOfType(featureObject, SimpleStatement.class);
Invocation inv = EcoreUtil2.getContainerOfType(featureObject, Invocation.class);
List<TypeItem> allTypes = null;
int actualOffset = -1;
if (statement != null && statement.getRight() != null && statement.getLeft() == featureObject)
{
actualOffset = NodeModelUtils.findActualNodeFor(statement).getTotalEndOffset();
}
else if (inv != null && inv.getParams().contains(featureObject))
{
actualOffset = NodeModelUtils.findActualNodeFor(featureObject).getTotalEndOffset();
}
else if (inv == null && statement == null && variable instanceof FormalParam)
{
actualOffset = NodeModelUtils.findActualNodeFor(featureObject).getTotalEndOffset();
}
else if (featureObject.eContainingFeature() == BslPackage.Literals.FOR_STATEMENT__VARIABLE_ACCESS)
{
if (featureObject.eContainer() instanceof ForEachStatement
&& ((ForEachStatement)featureObject.eContainer()).getCollection() != null)
{
actualOffset =
NodeModelUtils.findActualNodeFor(((ForEachStatement)featureObject.eContainer()).getCollection())
.getTotalEndOffset() + 1;
}
else if (featureObject.eContainer() instanceof ForToStatement
&& ((ForToStatement)featureObject.eContainer()).getInitializer() != null)
{
actualOffset =
NodeModelUtils.findActualNodeFor(((ForToStatement)featureObject.eContainer()).getInitializer())
.getTotalEndOffset() + 1;
}
}
if (actualOffset != -1 && variable.getTypeStateProvider() != null)
{
allTypes = new ArrayList<>();
List<VariableTypeState> nearestStates =
variable.getTypeStateProvider().get(TypeSystemMode.NORMAL).getNearestByOffset(envs, actualOffset);
for (VariableTypeState nearestState : nearestStates)
{
if (nearestState != null)
{
if (nearestState instanceof VariableTreeTypeStateWithSubStates)
{
for (VariableTreeTypeState subState : ((VariableTreeTypeStateWithSubStates)nearestState)
.getSubStates(envs))
{
subState.getTypes().forEach(allTypes::add);
}
}
else
{
nearestState.getTypes().forEach(allTypes::add);
}
}
}
}
else
{
allTypes = typeComputer.computeTypes(featureObject, envs);
}
return allTypes;
}
}

View File

@ -101,7 +101,7 @@ public class VariableTypeCheck
else if (object instanceof SimpleStatement && ((SimpleStatement)object).getLeft() instanceof StaticFeatureAccess
&& ((StaticFeatureAccess)((SimpleStatement)object).getLeft()).getImplicitVariable() != null)
{
EObject checkType = ((SimpleStatement)object).getRight();
EObject checkType = ((SimpleStatement)object).getLeft();
Variable variable = ((StaticFeatureAccess)((SimpleStatement)object).getLeft()).getImplicitVariable();
checkVariable(variable, checkType, resultAceptor, monitor);
}
@ -110,16 +110,19 @@ public class VariableTypeCheck
DeclareStatement declare = (DeclareStatement)object;
for (Variable variable : declare.getVariables())
{
if (monitor.isCanceled())
{
return;
}
checkVariable(variable, variable, resultAceptor, monitor);
}
}
}
private void checkVariable(Variable variable, EObject checkObject, ResultAcceptor resultAceptor,
IProgressMonitor monitor)
{
if (!monitor.isCanceled() && checkObject != null && variable != null && isEmptyTypes(checkObject))
if (checkObject != null && variable != null && isEmptyTypes(checkObject) && !monitor.isCanceled())
{
String message =
MessageFormat.format(Messages.VariableTypeCheck_Variable_M_has_no_value_type, variable.getName());

View File

@ -7,5 +7,22 @@ EndProcedure
Procedure Complaint() Export
Var TestVar; // Number
// empty
MyArray = NewArray();
EndProcedure
// Parameters:
// Object - Arbitrary
// AttributeName - String
Procedure Complaint2(Object, AttributeName) Export
TestVar2 = Object[AttributeName]; // Number
EndProcedure
// Returns:
// Array of Number - new array
Function NewArray()
EndFunction

View File

@ -149,7 +149,7 @@ public class CommonModuleStrictTypesTest
Module module = updateAndGetModule(checkId);
List<Variable> variables = EcoreUtil2.eAllOfType(module, Variable.class);
assertEquals(2, variables.size());
assertEquals(4, variables.size());
List<Marker> markers = getMarters(checkId, module);