Commit 53f82990 authored by Adam Knapp's avatar Adam Knapp
Browse files

Fixing subtype checking (issue #447)


Signed-off-by: Adam Knapp's avatarAdam Knapp <adam.knapp@ericsson.com>
parent 172e5373
......@@ -337,15 +337,23 @@ public interface IType extends IGovernor, IIdentifierContainer, IVisitableNode,
public final boolean implicit_omit;
/** true if the value to be checked is an element of a string */
public final boolean str_elem;
/** whether the value checking is initiated by a subtype */
public final boolean from_subtype;
public ValueCheckingOptions(final Expected_Value_type expectedValue, final boolean incompleteAllowed, final boolean omitAllowed,
final boolean subCheck, final boolean implicitOmit, final boolean strElem) {
this(expectedValue, incompleteAllowed, omitAllowed, subCheck, implicitOmit, strElem, false);
}
public ValueCheckingOptions(final Expected_Value_type expectedValue, final boolean incompleteAllowed, final boolean omitAllowed,
final boolean subCheck, final boolean implicitOmit, final boolean strElem, final boolean fromSubtype) {
this.expected_value = expectedValue;
this.incomplete_allowed = incompleteAllowed;
this.omit_allowed = omitAllowed;
this.sub_check = subCheck;
this.implicit_omit = implicitOmit;
this.str_elem = strElem;
this.from_subtype = fromSubtype;
}
}
......
......@@ -375,7 +375,7 @@ public final class Referenced_Type extends ASN1Type implements IReferencingType
if (tempType != this) {
selfReference = tempType.checkThisValue(timestamp, value, lhs, new ValueCheckingOptions(valueCheckingOptions.expected_value,
valueCheckingOptions.incomplete_allowed, valueCheckingOptions.omit_allowed, false, valueCheckingOptions.implicit_omit,
valueCheckingOptions.str_elem));
valueCheckingOptions.str_elem, valueCheckingOptions.from_subtype));
final Definition def = value.getDefiningAssignment();
if (def != null) {
final String referingModuleName = getMyScope().getModuleScope().getName();
......
......@@ -484,7 +484,7 @@ public final class TTCN3_Sequence_Type extends TTCN3_Set_Seq_Choice_BaseType {
} else {
selfReference = checkThisValueSeq_T(timestamp, (Sequence_Value) last, lhs, valueCheckingOptions.expected_value,
valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit,
valueCheckingOptions.str_elem);
valueCheckingOptions.str_elem, valueCheckingOptions.from_subtype, false);
}
break;
case SEQUENCEOF_VALUE:
......@@ -501,7 +501,7 @@ public final class TTCN3_Sequence_Type extends TTCN3_Set_Seq_Choice_BaseType {
} else {
selfReference = checkThisValueSeq_T(timestamp, (Sequence_Value) last, lhs, valueCheckingOptions.expected_value,
valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit,
valueCheckingOptions.str_elem);
valueCheckingOptions.str_elem, valueCheckingOptions.from_subtype, true);
}
}
break;
......@@ -549,9 +549,12 @@ public final class TTCN3_Sequence_Type extends TTCN3_Set_Seq_Choice_BaseType {
* @param implicitOmit
* true if the implicit omit optional attribute was set
* for the value, false otherwise
* @param strElem true, if the value to be checked is an element of a string
* @param fromSubtype whether the value check is initiated from a subtype
* @param isValueListNotation whether the value is given with value list notation or with assignment notation
* */
private boolean checkThisValueSeq_T(final CompilationTimeStamp timestamp, final Sequence_Value value, final Assignment lhs, final Expected_Value_type expectedValue,
final boolean incompleteAllowed, final boolean implicitOmit, final boolean strElem) {
final boolean incompleteAllowed, final boolean implicitOmit, final boolean strElem, final boolean fromSubtype, final boolean isValueListNotation) {
boolean selfReference = false;
check(timestamp);
final CompilationTimeStamp valueTimeStamp = value.getLastTimeChecked();
......@@ -562,6 +565,7 @@ public final class TTCN3_Sequence_Type extends TTCN3_Set_Seq_Choice_BaseType {
final Map<String, NamedValue> componentMap = new HashMap<String, NamedValue>();
final Map<String, CompField> realComponents = compFieldMap.getComponentFieldMap(timestamp);
final boolean localIncompleteAllowed = incompleteAllowed || (fromSubtype && !isValueListNotation);
boolean inSnyc = true;
final int nofTypeComponents = realComponents.size();
final int nofValueComponents = value.getNofComponents();
......@@ -590,7 +594,7 @@ public final class TTCN3_Sequence_Type extends TTCN3_Set_Seq_Choice_BaseType {
final CompField componentField = realComponents.get(valueId.getName());
if (inSnyc) {
if (incompleteAllowed) {
if (localIncompleteAllowed) {
boolean found = false;
for (int j = nextIndex; j < nofTypeComponents && !found; j++) {
......@@ -629,26 +633,26 @@ public final class TTCN3_Sequence_Type extends TTCN3_Set_Seq_Choice_BaseType {
if (componentValue != null) {
componentValue.setMyGovernor(type);
if (Value_type.NOTUSED_VALUE.equals(componentValue.getValuetype())) {
if (!incompleteAllowed) {
if (!localIncompleteAllowed) {
componentValue.getLocation().reportSemanticWarning(INCOMPLETEPRESENTERROR);
}
} else {
final IValue tempValue = type.checkThisValueRef(timestamp, componentValue);
selfReference |= type.checkThisValue(timestamp, tempValue, lhs, new ValueCheckingOptions(expectedValue, incompleteAllowed,
componentField.isOptional(), true, implicitOmit, strElem));
componentField.isOptional(), true, implicitOmit, strElem, fromSubtype));
}
}
}
}
if (!incompleteAllowed || implicitOmit || strictConstantCheckingSeverity) {
if (!localIncompleteAllowed || implicitOmit || strictConstantCheckingSeverity) {
for (int i = 0; i < nofTypeComponents; i++) {
final Identifier id = compFieldMap.fields.get(i).getIdentifier();
if (!componentMap.containsKey(id.getName())) {
if (getComponentByIndex(i).isOptional() && implicitOmit) {
value.addNamedValue(new NamedValue(new Identifier(Identifier_type.ID_TTCN, id.getDisplayName()),
new Omit_Value(), false));
} else if (!incompleteAllowed || strictConstantCheckingSeverity) {
} else if (!localIncompleteAllowed || strictConstantCheckingSeverity) {
value.getLocation().reportSemanticError(MessageFormat.format(MISSINGFIELDTTCN3, id.getDisplayName()));
}
}
......
......@@ -402,7 +402,8 @@ public final class TTCN3_Set_Type extends TTCN3_Set_Seq_Choice_BaseType implemen
valueCheckingOptions.implicit_omit, valueCheckingOptions.str_elem);
} else {
selfReference = checkThisValueSet_T(timestamp, (Set_Value) last, lhs, valueCheckingOptions.expected_value,
valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit, valueCheckingOptions.str_elem);
valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit,
valueCheckingOptions.str_elem, valueCheckingOptions.from_subtype, false);
}
break;
case SEQUENCEOF_VALUE:
......@@ -419,6 +420,7 @@ public final class TTCN3_Set_Type extends TTCN3_Set_Seq_Choice_BaseType implemen
value.setIsErroneous(true);
}
} else {
// TODO: allow value list notation for set
value.getLocation().reportSemanticError(
MessageFormat.format(last.isAsn() ? VALUELISTNOTATIONERRORASN1 : VALUELISTNOTATIONERRORTTCN3, getFullName()));
value.setIsErroneous(true);
......@@ -431,7 +433,8 @@ public final class TTCN3_Set_Type extends TTCN3_Set_Seq_Choice_BaseType implemen
valueCheckingOptions.implicit_omit, valueCheckingOptions.str_elem);
} else {
selfReference = checkThisValueSet_T(timestamp, (Set_Value) last, lhs, valueCheckingOptions.expected_value,
valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit, valueCheckingOptions.str_elem);
valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit,
valueCheckingOptions.str_elem, valueCheckingOptions.from_subtype, false);
}
break;
case UNDEFINED_BLOCK:
......@@ -473,14 +476,20 @@ public final class TTCN3_Set_Type extends TTCN3_Set_Seq_Choice_BaseType implemen
* @param incompleteAllowed whether incomplete value is allowed or not.
* @param implicitOmit true if the implicit omit optional attribute was set
* for the value, false otherwise
* @param strElem true, if the value to be checked is an element of a string
* @param fromSubtype whether the value check is initiated from a subtype
* @param isValueListNotation whether the value is given with value list notation or with assignment notation
*
* */
private boolean checkThisValueSet_T(final CompilationTimeStamp timestamp, final Set_Value value, final Assignment lhs, final Expected_Value_type expectedValue,
final boolean incompleteAllowed, final boolean implicitOmit, final boolean strElem) {
final boolean incompleteAllowed, final boolean implicitOmit, final boolean strElem, final boolean fromSubtype, final boolean isValueListNotation) {
value.removeGeneratedValues();
boolean selfReference = false;
final Map<String, NamedValue> componentMap = new HashMap<String, NamedValue>();
final Map<String, CompField> realComponents = compFieldMap.getComponentFieldMap(timestamp);
final boolean localIncompleteAllowed = incompleteAllowed || (fromSubtype && !isValueListNotation);
final int nofValueComponents = value.getNofComponents();
for (int i = 0; i < nofValueComponents; i++) {
......@@ -507,19 +516,20 @@ public final class TTCN3_Set_Type extends TTCN3_Set_Seq_Choice_BaseType implemen
if (componentValue != null) {
componentValue.setMyGovernor(type);
if (Value_type.NOTUSED_VALUE.equals(componentValue.getValuetype())) {
if (!incompleteAllowed) {
if (!localIncompleteAllowed) {
componentValue.getLocation().reportSemanticError(INCOMPLETEPRESENTERROR);
}
} else {
final IValue tempValue = type.checkThisValueRef(timestamp, componentValue);
selfReference |= type.checkThisValue(timestamp, tempValue, lhs,
new ValueCheckingOptions(expectedValue, incompleteAllowed, componentField.isOptional(), true, implicitOmit, strElem));
new ValueCheckingOptions(expectedValue, incompleteAllowed, componentField.isOptional(),
true, implicitOmit, strElem, fromSubtype));
}
}
}
}
if (!incompleteAllowed || implicitOmit || strictConstantCheckingSeverity) {
if (!localIncompleteAllowed || implicitOmit || strictConstantCheckingSeverity) {
final int nofTypeComponents = realComponents.size();
CompField field;
for (int i = 0; i < nofTypeComponents; i++) {
......@@ -528,7 +538,7 @@ public final class TTCN3_Set_Type extends TTCN3_Set_Seq_Choice_BaseType implemen
if (!componentMap.containsKey(id.getName())) {
if (field.isOptional() && implicitOmit) {
value.addNamedValue(new NamedValue(new Identifier(Identifier_type.ID_TTCN, id.getDisplayName()), new Omit_Value(), false));
} else if (!incompleteAllowed || strictConstantCheckingSeverity) {
} else if (!localIncompleteAllowed || strictConstantCheckingSeverity) {
value.getLocation().reportSemanticError(
MessageFormat.format(MISSINGFIELDTTCN3, id.getDisplayName()));
}
......
......@@ -330,8 +330,7 @@ public final class SubType implements IIncrementallyUpdateable {
}
myOwner.checkThisValue(timestamp, last, null, new ValueCheckingOptions(Expected_Value_type.EXPECTED_CONSTANT,
(subtypeType == SubType_type.ST_RECORD || subtypeType == SubType_type.ST_SET),
false, false, false, false));
false, false, false, false, false, true));
final IReferenceChain chain = ReferenceChain.getInstance(IReferenceChain.CIRCULARREFERENCE, true);
last = last.getValueRefdLast(timestamp, chain);
chain.release();
......
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