use of org.eclipse.titan.designer.AST.TTCN3.types.subtypes.Length_ParsedSubType in project titan.EclipsePlug-ins by eclipse.
the class SubType method check.
/**
* Does the semantic checking of the sub-type.
*
* @param timestamp
* the time stamp of the actual semantic check cycle.
*/
public void check(final CompilationTimeStamp timestamp) {
if (lastTimeChecked != null && !lastTimeChecked.isLess(timestamp)) {
return;
}
lastTimeChecked = timestamp;
if (parsedRestrictions != null) {
int addedCount = 0;
boolean hasSingle = false, hasRange = false;
for (int i = 0, size = parsedRestrictions.size(); i < size; i++) {
boolean added = false;
final ParsedSubType parsed = parsedRestrictions.get(i);
switch(parsed.getSubTypetype()) {
case SINGLE_PARSEDSUBTYPE:
hasSingle = true;
added = addTtcnSingle(timestamp, ((Single_ParsedSubType) parsed).getValue(), i);
break;
case RANGE_PARSEDSUBTYPE:
hasRange = true;
final Range_ParsedSubType rpst = (Range_ParsedSubType) parsed;
added = addTtcnRange(timestamp, rpst.getMin(), rpst.getMinExclusive(), rpst.getMax(), rpst.getMaxExclusive(), i);
break;
case LENGTH_PARSEDSUBTYPE:
added = addTtcnLength(timestamp, ((Length_ParsedSubType) parsed).getLength(), i);
break;
case PATTERN_PARSEDSUBTYPE:
added = addTtcnPattern(timestamp, ((Pattern_ParsedSubType) parsed).getPattern(), i);
break;
default:
ErrorReporter.INTERNAL_ERROR();
}
if (added) {
addedCount++;
}
}
switch(subtypeType) {
case ST_CHARSTRING:
case ST_UNIVERSAL_CHARSTRING:
if (hasSingle && hasRange) {
myOwner.getLocation().reportSemanticError(MessageFormat.format("Mixing of value list and range subtyping is not allowed for type `{0}''", myOwner.getTypename()));
isErroneous = true;
return;
}
break;
default:
// TTCN-3 BNF itself
break;
}
if (addedCount < parsedRestrictions.size()) {
isErroneous = true;
return;
}
if (getIsErroneous(timestamp)) {
return;
}
}
// create the intersection of the two sub-types
if ((parentSubtype != null) && !parentSubtype.getIsErroneous(timestamp)) {
// check for circular sub-type reference
if (!addParentSubtype(parentSubtype)) {
isErroneous = true;
return;
}
if (parentSubtype.subtypeType != subtypeType) {
ErrorReporter.INTERNAL_ERROR();
return;
}
if (parentSubtype.subtypeConstraint != null) {
if (subtypeConstraint == null) {
subtypeConstraint = parentSubtype.subtypeConstraint;
} else {
// both own and inherited sub-type constraints exist
if (subtypeConstraint.isSubset(parentSubtype.subtypeConstraint) == TernaryBool.TFALSE) {
final String message = MessageFormat.format("The subtype restriction is not a subset of the restriction on the parent type. Subtype {0} is not subset of subtype {1}", subtypeConstraint.toString(), parentSubtype.subtypeConstraint.toString());
getParsedLocation().reportSemanticError(message);
isErroneous = true;
return;
}
subtypeConstraint = subtypeConstraint.intersection(parentSubtype.subtypeConstraint);
}
}
if (parentSubtype.lengthRestriction != null) {
if (lengthRestriction == null) {
lengthRestriction = parentSubtype.lengthRestriction;
} else {
lengthRestriction = lengthRestriction.intersection(parentSubtype.lengthRestriction);
}
}
}
// set is empty or full
if (subtypeConstraint != null) {
if (subtypeConstraint.isEmpty() == TernaryBool.TTRUE) {
getParsedLocation().reportSemanticError("The subtype is an empty set");
isErroneous = true;
return;
}
if (subtypeConstraint.isFull() == TernaryBool.TTRUE) {
getParsedLocation().reportSemanticWarning(MessageFormat.format("The subtype of type `{0}'' is a full set, it does not constrain the root type.", myOwner.getTypename()));
subtypeConstraint = null;
}
}
if ((lengthRestriction != null) && (lengthRestriction.isFull() == TernaryBool.TTRUE)) {
lengthRestriction = null;
}
}
use of org.eclipse.titan.designer.AST.TTCN3.types.subtypes.Length_ParsedSubType in project titan.EclipsePlug-ins by eclipse.
the class AbstractOfType method isSubtypeCompatible.
/**
* Checks that the provided type is sub-type compatible with the actual
* set of type.
* <p>
* In case of sequence/set/array this means that the number of their
* fields fulfills the length restriction of the set of type.
*
* @param timestamp
* the timestamp of the actual semantic check cycle
* @param other
* the type to check against.
*
* @return true if they are sub-type compatible, false otherwise.
*/
public boolean isSubtypeCompatible(final CompilationTimeStamp timestamp, final IType other) {
if (subType == null || other == null) {
return true;
}
long nofComponents;
switch(other.getTypetype()) {
case TYPE_ASN1_SEQUENCE:
nofComponents = ((ASN1_Sequence_Type) other).getNofComponents(timestamp);
break;
case TYPE_TTCN3_SEQUENCE:
nofComponents = ((TTCN3_Sequence_Type) other).getNofComponents();
break;
case TYPE_ASN1_SET:
nofComponents = ((ASN1_Set_Type) other).getNofComponents(timestamp);
break;
case TYPE_TTCN3_SET:
nofComponents = ((TTCN3_Set_Type) other).getNofComponents();
break;
case TYPE_SEQUENCE_OF:
case TYPE_SET_OF:
if (other.getSubtype() == null) {
return true;
}
return subType.isCompatible(timestamp, other.getSubtype());
case TYPE_ARRAY:
{
final ArrayDimension dimension = ((Array_Type) other).getDimension();
if (dimension.getIsErroneous(timestamp)) {
return false;
}
nofComponents = dimension.getSize();
break;
}
default:
return false;
}
final List<ParsedSubType> tempRestrictions = new ArrayList<ParsedSubType>(1);
final Integer_Value length = new Integer_Value(nofComponents);
tempRestrictions.add(new Length_ParsedSubType(new SingleLenghtRestriction(length)));
final SubType tempSubtype = new SubType(getSubtypeType(), this, tempRestrictions, null);
tempSubtype.check(timestamp);
return subType.isCompatible(timestamp, tempSubtype);
}
Aggregations