Commit 638f3228 authored by Adam Knapp's avatar Adam Knapp
Browse files

Advanced matching semantic check improvements #413 #414 #415


Signed-off-by: Adam Knapp's avatarAdam Knapp <adam.knapp@ericsson.com>
parent bc3612e0
......@@ -76,8 +76,8 @@ public class Reference extends ASTNode implements ILocateableNode, IIncrementall
public static final String TYPEEXPECTED = "Type reference expected";
public static final String ASN1SETTINGEXPECTED = "Reference to ASN.1 setting expected";
private static final String INVALIDVALUEREFERENCE = "Invalid `value` reference";
private static final String VALUENOTSETTER = "A property getter cannot have a `value` reference";
private static final String INVALIDVALUEREFERENCE = "Reference to `value` is not allowed here";
private static final String VALUENOTSETTER = "Reference to `value` is not allowed in a property getter";
public enum Ref_Type {
/** basic reference (not related to a class scope or a dynamic template) */
......@@ -514,13 +514,13 @@ public class Reference extends ASTNode implements ILocateableNode, IIncrementall
final StatementBlock sb = (StatementBlock)getMyScope();
FormalParameter valueParam = getValueParameter(sb);
if (valueParam != null) {
return (Assignment)valueParam;
return valueParam;
} else {
if (sb.ownerIsProperty() && ! sb.isPropertySetter()) {
getLocation().reportSemanticError(VALUENOTSETTER);
return null;
} else {
getLocation().reportSemanticError(INVALIDVALUEREFERENCE);
}
getLocation().reportSemanticError(INVALIDVALUEREFERENCE);
return null;
}
}
......
......@@ -29,6 +29,7 @@ import org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Function;
import org.eclipse.titan.designer.AST.TTCN3.definitions.Definition;
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.types.Boolean_Type;
import org.eclipse.titan.designer.AST.TTCN3.types.Property_Type;
import org.eclipse.titan.designer.AST.TTCN3.values.expressions.ExpressionStruct;
import org.eclipse.titan.designer.compiler.JavaGenData;
......@@ -53,8 +54,9 @@ public final class Return_Statement extends Statement {
+ "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 RETURNINDYNAMICTEMPLATESB = "The dynamic template's statement block should return a boolean value";
private static final String RETURNINDYNAMICTEMPLATEREF = "The dynamic template's referenced function should return a boolean value";
private static final String INVALIDRETURNINDYNAMICTEMPLATESB1 =
"Missing return value. The dynamic template's statement block should return a boolean value";
private static final String INVALIDRETURNINDYNAMICTEMPLATESB2 = "A specific value without matching symbols was expected as return value";
private static final String FULLNAMEPART = ".returnexpression";
private static final String STATEMENT_NAME = "return";
private static final String RETURNTYPEEXPECTED = "Return type `{0}'' expected";
......@@ -143,10 +145,10 @@ public final class Return_Statement extends Statement {
template.getLocation().reportSemanticError(UNEXPECTEDRETURNVALUE);
}
break;
case A_FUNCTION_RVAL:
case A_FUNCTION_RVAL: {
final Type returnType = ((Def_Function) definition).getType(timestamp);
if (template == null) {
location.reportSemanticError(MessageFormat.format(MISSINGVALUE, returnType.getTypename()));
location.reportSemanticError(MessageFormat.format(MISSINGVALUE, returnType.getTypename()));
break;
}
if (!template.isValue(timestamp)) {
......@@ -161,28 +163,28 @@ public final class Return_Statement extends Statement {
returnType.checkThisValueRef(timestamp, value);
returnType.checkThisValue(timestamp, value, null, new ValueCheckingOptions(Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false, false, true, false, false));
}
break;
case A_FUNCTION_RTEMP:
}
case A_FUNCTION_RTEMP: {
if (template == null) {
location.reportSemanticError(MessageFormat.format(MISSINGTEMPLATE, ((Def_Function) definition).getType(timestamp)
.getTypename()));
} else {
final Type returnType1 = ((Def_Function) definition).getType(timestamp);
template.setMyGovernor(returnType1);
final ITTCN3Template temporalTemplate1 = returnType1.checkThisTemplateRef(timestamp, template,Expected_Value_type.EXPECTED_TEMPLATE,null);
temporalTemplate1.checkThisTemplateGeneric(timestamp, returnType1, true, true, true, true, true, null);
genRestrictionCheck = TemplateRestriction.check(timestamp, definition, temporalTemplate1, null);
final Type returnType = ((Def_Function) definition).getType(timestamp);
template.setMyGovernor(returnType);
final ITTCN3Template temporalTemplate = returnType.checkThisTemplateRef(timestamp, template,Expected_Value_type.EXPECTED_TEMPLATE,null);
temporalTemplate.checkThisTemplateGeneric(timestamp, returnType, true, true, true, true, true, null);
genRestrictionCheck = TemplateRestriction.check(timestamp, definition, temporalTemplate, null);
}
break;
}
case A_ALTSTEP:
if (template != null) {
template.getLocation().reportSemanticError(ALTSTEPRETURNINGVALUE);
}
break;
// class property getter/setter
case A_VAR:
case A_VAR: {
if (myStatementBlock.ownerIsProperty()) {
if (myStatementBlock.isPropertyGetter()) {
final INamedNode node = myStatementBlock.getNameParent();
......@@ -207,19 +209,28 @@ public final class Return_Statement extends Statement {
}
}
break;
}
// dynamic match template
case A_TEMPLATE:
case A_VAR_TEMPLATE:
if (myStatementBlock.isInDynamicTemplate() && template != null &&
!Type_type.TYPE_BOOL.equals(
template.getExpressionReturntype(timestamp, Expected_Value_type.EXPECTED_DYNAMIC_VALUE))) {
if (myStatementBlock.getDynamicTemplate().hasReference()) {
myStatementBlock.getDynamicTemplate().getLocation().reportSemanticError(RETURNINDYNAMICTEMPLATEREF);
} else {
myStatementBlock.getDynamicTemplate().getLocation().reportSemanticError(RETURNINDYNAMICTEMPLATESB);
}
case A_VAR_TEMPLATE: {
if (myStatementBlock.isInDynamicTemplate() && template == null) {
myStatementBlock.getDynamicTemplate().getLocation().reportSemanticError(INVALIDRETURNINDYNAMICTEMPLATESB1);
} else if (myStatementBlock.isInDynamicTemplate() && !template.isValue(timestamp)) {
myStatementBlock.getDynamicTemplate().getLocation().reportSemanticError(INVALIDRETURNINDYNAMICTEMPLATESB2);
}
if (template == null) {
break;
}
final Type returnType = new Boolean_Type();
template.setMyGovernor(returnType);
final IValue value = template.getValue();
if (value != null) {
value.setMyGovernor(returnType);
returnType.checkThisValueRef(timestamp, value);
returnType.checkThisValue(timestamp, value, null, new ValueCheckingOptions(Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false, false, true, false, false));
}
break;
}
default:
location.reportSemanticError(MessageFormat.format(UNEXPETEDRETURNSTATEMENT, definition.getAssignmentName()));
break;
......
......@@ -30,6 +30,7 @@ import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
* @author Adam Knapp
* */
public class ConjunctionMatch_template extends CompositeTemplate {
private static final String ANYOROMITWARNING = "`*'' in complemented list. This template will not match anything.";
public ConjunctionMatch_template(final ListOfTemplates templates) {
super(templates);
......@@ -74,13 +75,18 @@ public class ConjunctionMatch_template extends CompositeTemplate {
if (type == null) {
return false;
}
final boolean allowOmitInValueList = TTCN3Template.allowOmitInValueList(getLocation(), allowOmit);
boolean selfReference = false;
for (int i = 0, size = templates.getNofTemplates(); i < size; i++) {
final TTCN3Template component = templates.getTemplateByIndex(i);
component.setMyGovernor(type);
final ITTCN3Template temporalComponent = type.checkThisTemplateRef(timestamp, component);
selfReference |= temporalComponent.checkThisTemplateGeneric(timestamp, type, false, false, true, subCheck, implicitOmit, lhs);
selfReference |= temporalComponent.checkThisTemplateGeneric(timestamp, type, false, allowOmitInValueList, true, subCheck, implicitOmit, lhs);
if (Template_type.ANY_OR_OMIT.equals(temporalComponent.getTemplatetype())) {
component.getLocation().reportSemanticWarning(ANYOROMITWARNING);
}
}
checkLengthRestriction(timestamp, type);
......
......@@ -16,6 +16,7 @@ import org.eclipse.titan.designer.AST.Assignment.Assignment_type;
import org.eclipse.titan.designer.AST.IReferenceChain;
import org.eclipse.titan.designer.AST.IType;
import org.eclipse.titan.designer.AST.Identifier;
import org.eclipse.titan.designer.AST.NULL_Location;
import org.eclipse.titan.designer.AST.Identifier.Identifier_type;
import org.eclipse.titan.designer.AST.Reference;
import org.eclipse.titan.designer.AST.Scope;
......@@ -36,6 +37,9 @@ import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
* @author Adam Knapp
* */
public class DynamicMatch_template extends TTCN3Template {
private static final String MISSINGRETURN = "The dynamic template's statement block does not have a return statement";
private static final String LEAVEWITHOUTRETURN =
"Control might leave the dynamic template's statement block without reaching a return statement";
/** function reference used in defining the dynamic template, not owned */
private Reference reference;
......@@ -68,14 +72,6 @@ public class DynamicMatch_template extends TTCN3Template {
this.setMyScope(block);
}
public void addValueParamList(final Type type) {
final FormalParameter valueParam = new FormalParameter(null, Assignment_type.A_PAR_VAL_IN, type, new Identifier(Identifier_type.ID_TTCN, "value"), null, null);
final List<FormalParameter> paramList = new ArrayList<FormalParameter>();
paramList.add(valueParam);
final FormalParameterList fpList = new FormalParameterList(paramList);
statementBlock.setValueParamList(fpList);
}
@Override
public String createStringRepresentation() {
final StringBuilder builder = new StringBuilder();
......@@ -120,23 +116,47 @@ public class DynamicMatch_template extends TTCN3Template {
return false;
}
boolean selfReference = type.checkThisTemplate(timestamp, this, isModified, implicitOmit, lhs);
checkLengthRestriction(timestamp, type);
final Type myType = (Type)statementBlock.getMyDefinition().getType(timestamp);
addValueParamList(myType);
final FormalParameter valueParam =
new FormalParameter(null, Assignment_type.A_PAR_VAL_IN, myType, new Identifier(Identifier_type.ID_TTCN, "value"), null, null);
final List<FormalParameter> paramList = new ArrayList<FormalParameter>();
paramList.add(valueParam);
final FormalParameterList fpList = new FormalParameterList(paramList);
fpList.setFullNameParent(this);
fpList.setMyScope(this.getMyScope());
statementBlock.setValueParamList(fpList);
statementBlock.getValueParamList().check(timestamp, null);
statementBlock.check(timestamp);
switch (statementBlock.hasReturn(timestamp)) {
case RS_NO:
location.reportSemanticError(MISSINGRETURN);
break;
case RS_MAYBE:
location.reportSemanticError(LEAVEWITHOUTRETURN);
break;
default:
break;
}
checkLengthRestriction(timestamp, type);
if (!allowOmit && isIfpresent) {
if (location != null && !(location instanceof NULL_Location)) {
location.reportSemanticError("`ifpresent' is not allowed here");
}
}
if (reference == null) {
return false;
}
final Assignment assignment = reference.getRefdAssignment(timestamp, true);
if (assignment == null) {
return false;
}
selfReference |= lhs == assignment;
boolean selfReference = lhs == assignment;
assignment.check(timestamp);
IType governor = assignment.getType(timestamp);
......@@ -145,7 +165,6 @@ public class DynamicMatch_template extends TTCN3Template {
}
if (governor == null) {
setIsErroneous(true);
return selfReference;
}
return selfReference;
......
......@@ -71,17 +71,11 @@ public class ImplicationMatch_template extends TTCN3Template {
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) {
boolean selfReference = type.checkThisTemplate(timestamp, this, isModified, implicitOmit, lhs);
ITTCN3Template temporalComponent = type.checkThisTemplateRef(timestamp, precondition.getTemplateBody());
selfReference |= temporalComponent.checkThisTemplateGeneric(timestamp, type, false, false, true, subCheck, implicitOmit, lhs);
temporalComponent = type.checkThisTemplateRef(timestamp, implied_template.getTemplateBody());
selfReference |= temporalComponent.checkThisTemplateGeneric(timestamp, type, false, false, true, subCheck, implicitOmit, lhs);
precondition.check(timestamp, type);
implied_template.check(timestamp, type);
checkLengthRestriction(timestamp, type);
return selfReference;
return false;
}
@Override
......
......@@ -2214,7 +2214,10 @@ pr_TemplateBody returns[ TTCN3Template template]
| t4 = pr_SimpleSpec { $template = $t4.template; }
)
( pr_ExtraMatchingAttributes[$template] )?
( t5 = pr_ImplicationMatch { implied_template = $t5.implied_template; } )?
(
( t5 = pr_ImplicationMatch { implied_template = $t5.implied_template; } )
( pr_ExtraMatchingAttributes[$template] )?
)?
| dc = pr_DecodedContentMatch { $template = $dc.template; }
)
{
......
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