Commit 0f066cca authored by Adam Knapp's avatar Adam Knapp
Browse files

Dynamic matching semantic check improvements #413


Signed-off-by: Adam Knapp's avatarAdam Knapp <adam.knapp@ericsson.com>
parent b7b0c694
......@@ -35,6 +35,7 @@ import org.eclipse.titan.designer.AST.TypeCompatibilityInfo;
import org.eclipse.titan.designer.AST.TTCN3.TemplateRestriction;
import org.eclipse.titan.designer.AST.TTCN3.TemplateRestriction.Restriction_type;
import org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameter.parameterEvaluationType;
import org.eclipse.titan.designer.AST.TTCN3.templates.DynamicMatch_template;
import org.eclipse.titan.designer.AST.TTCN3.templates.ITTCN3Template;
import org.eclipse.titan.designer.AST.TTCN3.templates.ITTCN3Template.Template_type;
import org.eclipse.titan.designer.AST.TTCN3.templates.PatternString.PatternType;
......@@ -158,6 +159,10 @@ public final class Def_Template extends Definition implements IParameterisedAssi
}
if (body != null) {
body.setFullNameParent(this);
if (body.getTemplatetype().equals(ITTCN3Template.Template_type.DYNAMIC_MATCH)) {
((DynamicMatch_template) body).getDynamicStatementBlock().setMyDefinition(this);
}
}
}
......
......@@ -46,9 +46,11 @@ public final class Return_Statement extends Statement {
private static final String MISSINGTEMPLATE = "Missing return template. The function should return a template of type `{0}''";
private static final String MISSINGVALUE = "Missing return value. The function should return a value of type `{0}''";
private static final String UNEXPECTEDRETURNVALUE = "Unexpected return value. The function does not have return type";
private static final String UNEXPETEDRETURNSTATEMENT = "Return statement cannot be used in a {0}. It is allowed only in functions and altsteps";
private static final String UNEXPETEDRETURNSTATEMENT = "Return statement cannot be used in a {0}. "
+ "It is allowed only in functions, altsteps, dynamic matching and class property getters";
private static final String ALTSTEPRETURNINGVALUE = "An altstep cannot return a value";
private static final String USAGEINCONTROLPART = "Return statement cannot be used in the control part. It is allowed only in functions and altsteps";
private static final String USAGEINCONTROLPART = "Return statement cannot be used in the control part. "
+ "It is allowed only in functions, altsteps, dynamic matching and class property getters";
private static final String RETURNINDESTRUCTOR = "Return statement cannot be used in a class destructor";
private static final String INVALIDSETTERRETURN = "Return statement cannot be used in a property setter";
private static final String RETURNINDYNAMICTEMPLATE = "The dynamic template's statement block should return a boolean value";
......@@ -146,11 +148,6 @@ public final class Return_Statement extends Statement {
location.reportSemanticError(MessageFormat.format(MISSINGVALUE, returnType.getTypename()));
break;
}
if (myStatementBlock.isInDynamicTemplate()
&& !returnType.getTypetype().equals(Type_type.TYPE_BOOL)) {
template.getLocation().reportSemanticError(RETURNINDYNAMICTEMPLATE);
break;
}
if (!template.isValue(timestamp)) {
template.getLocation().reportSemanticError(SPECIFICVALUEEXPECTED);
break;
......@@ -183,34 +180,40 @@ public final class Return_Statement extends Statement {
template.getLocation().reportSemanticError(ALTSTEPRETURNINGVALUE);
}
break;
// class property getter/setter
case A_VAR:
if (getMyScope() instanceof StatementBlock) {
final StatementBlock block = (StatementBlock)getMyScope();
if (block.ownerIsProperty() == true) {
if (block.isPropertyGetter()) {
final INamedNode node = block.getNameParent();
if (node instanceof Property_Type) {
final Property_Type property = (Property_Type)node;
if (template == null) {
if (myStatementBlock.ownerIsProperty()) {
if (myStatementBlock.isPropertyGetter()) {
final INamedNode node = myStatementBlock.getNameParent();
if (node instanceof Property_Type) {
final Property_Type property = (Property_Type)node;
if (template == null) {
final IType propType = property.getFieldType(timestamp, null, 0, Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false);
location.reportSemanticError(MessageFormat.format(MISSINGTEMPLATE, propType.getTypename()));
} else {
final Type_type templateType = template.getExpressionReturntype(timestamp, Expected_Value_type.EXPECTED_DYNAMIC_VALUE);
if (templateType != property.getTypetypeTtcn3()) {
final IType propType = property.getFieldType(timestamp, null, 0, Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false);
location.reportSemanticError(MessageFormat.format(MISSINGTEMPLATE, propType.getTypename()));
} else {
final Type_type templateType = template.getExpressionReturntype(timestamp, Expected_Value_type.EXPECTED_DYNAMIC_VALUE);
if (templateType != property.getTypetypeTtcn3()) {
final IType propType = property.getFieldType(timestamp, null, 0, Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false);
location.reportSemanticError(MessageFormat.format(RETURNTYPEEXPECTED, propType.getTypename()));
}
location.reportSemanticError(MessageFormat.format(RETURNTYPEEXPECTED, propType.getTypename()));
}
return;
}
}
if (block.isPropertySetter()) {
location.reportSemanticError(INVALIDSETTERRETURN);
return;
}
}
}
}
if (myStatementBlock.isPropertySetter()) {
location.reportSemanticError(INVALIDSETTERRETURN);
return;
}
}
break;
// dynamic match template
case A_TEMPLATE:
if (myStatementBlock.isInDynamicTemplate() && template != null &&
!Type_type.TYPE_BOOL.equals(
template.getExpressionReturntype(timestamp, Expected_Value_type.EXPECTED_DYNAMIC_VALUE))) {
myStatementBlock.getDynamicTemplate().getLocation().reportSemanticError(RETURNINDYNAMICTEMPLATE);
}
break;
default:
location.reportSemanticError(MessageFormat.format(UNEXPETEDRETURNSTATEMENT, definition.getAssignmentName()));
break;
......
......@@ -10,8 +10,10 @@ package org.eclipse.titan.designer.AST.TTCN3.templates;
import org.eclipse.titan.common.logging.ErrorReporter;
import org.eclipse.titan.designer.AST.Assignment;
import org.eclipse.titan.designer.AST.IReferenceChain;
import org.eclipse.titan.designer.AST.IType;
import org.eclipse.titan.designer.AST.Reference;
import org.eclipse.titan.designer.AST.Scope;
import org.eclipse.titan.designer.AST.TTCN3.Expected_Value_type;
import org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameter;
import org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameterList;
import org.eclipse.titan.designer.AST.TTCN3.statements.Return_Statement;
......@@ -73,8 +75,11 @@ public class DynamicMatch_template extends TTCN3Template {
@Override
public boolean checkExpressionSelfReferenceTemplate(final CompilationTimeStamp timestamp, final Assignment lhs) {
// TODO Auto-generated method stub
return false;
if (reference == null) {
return false;
}
return reference.getRefdAssignment(timestamp, false) == lhs;
}
@Override
......@@ -85,8 +90,45 @@ public class DynamicMatch_template extends TTCN3Template {
@Override
public void checkSpecificValue(final CompilationTimeStamp timestamp, final boolean allowOmit) {
// TODO Auto-generated method stub
final TTCN3Template temp = getTemplateReferencedLast(timestamp);
if (temp != this && !temp.getIsErroneous(timestamp)) {
temp.checkSpecificValue(timestamp, allowOmit);
}
}
@Override
/** {@inheritDoc} */
public boolean checkThisTemplateGeneric(final CompilationTimeStamp timestamp, final IType type, final boolean isModified,
final boolean allowOmit, final boolean allowAnyOrOmit, final boolean subCheck, final boolean implicitOmit, final Assignment lhs) {
if (getIsErroneous(timestamp)) {
return false;
}
statementBlock.check(timestamp);
if (reference == null) {
return false;
}
final Assignment assignment = reference.getRefdAssignment(timestamp, true);
if (assignment == null) {
return false;
}
final boolean selfReference = lhs == assignment;
assignment.check(timestamp);
IType governor = assignment.getType(timestamp);
if (governor != null) {
governor = governor.getFieldType(timestamp, reference, 1, Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false);
}
if (governor == null) {
setIsErroneous(true);
return selfReference;
}
return selfReference;
}
@Override
......
......@@ -25,6 +25,7 @@ import org.eclipse.titan.designer.AST.TypeCompatibilityInfo;
import org.eclipse.titan.designer.AST.Value;
import org.eclipse.titan.designer.AST.TTCN3.Expected_Value_type;
import org.eclipse.titan.designer.AST.TTCN3.attributes.RawAST;
import org.eclipse.titan.designer.AST.TTCN3.templates.ConjunctionMatch_template;
import org.eclipse.titan.designer.AST.TTCN3.templates.ITTCN3Template;
import org.eclipse.titan.designer.AST.TTCN3.templates.TTCN3Template;
import org.eclipse.titan.designer.AST.TTCN3.templates.ValueList_Template;
......@@ -280,15 +281,26 @@ public final class Integer_Type extends Type {
template.setIsErroneous(true);
}
break;
case VALUE_LIST:
case VALUE_LIST: {
final ValueList_Template temp = (ValueList_Template) template;
for (int i = 0; i < temp.getNofTemplates(); i++){
final TTCN3Template tmp = temp.getTemplateByIndex(i);
selfReference |= checkThisTemplate(timestamp,tmp,isModified,implicitOmit, lhs);
}
break;
}
case CONJUNCTION_MATCH: {
final ConjunctionMatch_template temp = (ConjunctionMatch_template) template;
for (int i = 0; i < temp.getNofTemplates(); i++) {
final TTCN3Template tmp = temp.getTemplateByIndex(i);
selfReference |= checkThisTemplate(timestamp ,tmp, isModified, implicitOmit, lhs);
}
break;
}
case ANY_OR_OMIT:
case ANY_VALUE:
case DYNAMIC_MATCH:
case IMPLICATION_MATCH:
//Allowed
break;
default:
......
......@@ -4941,7 +4941,7 @@ public class AST_tests {
markersToCheck.add(new MarkerToCheck("Too few parameters: 1 was expected instead of 0", lineNum, IMarker.SEVERITY_ERROR));
lineNum += 1;
for (i = 0; i < 2; i++) {
markersToCheck.add(new MarkerToCheck("Return statement cannot be used in the control part. It is allowed only in functions and altsteps", lineNum++, IMarker.SEVERITY_ERROR));
markersToCheck.add(new MarkerToCheck("Return statement cannot be used in the control part. It is allowed only in functions, altsteps, dynamic matching and class property getters", lineNum++, IMarker.SEVERITY_ERROR));
}
 
return markersToCheck;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment