@Override public void checkThisValue( final CompilationTimeStamp timestamp, final IValue value, final ValueCheckingOptions valueCheckingOptions) { super.checkThisValue(timestamp, value, valueCheckingOptions); IValue last = value.getValueRefdLast(timestamp, valueCheckingOptions.expected_value, null); if (null == last || last.getIsErroneous(timestamp)) { return; } // already handled ones switch (value.getValuetype()) { case OMIT_VALUE: case REFERENCED_VALUE: return; case UNDEFINED_LOWERIDENTIFIER_VALUE: if (Value_type.REFERENCED_VALUE.equals(last.getValuetype())) { return; } break; default: break; } switch (last.getValuetype()) { case UNDEFINED_BLOCK: last = last.setValuetype(timestamp, Value_type.CHARSYMBOLS_VALUE); if (last.getIsErroneous(timestamp)) { return; } last.setValuetype(timestamp, Value_type.UNIVERSALCHARSTRING_VALUE); break; case CHARSYMBOLS_VALUE: case CHARSTRING_VALUE: last.setValuetype(timestamp, Value_type.UNIVERSALCHARSTRING_VALUE); break; case ISO2022STRING_VALUE: location.reportSemanticError(UniversalCharstring_Value.ISOCONVERTION); setIsErroneous(true); break; case UNIVERSALCHARSTRING_VALUE: break; case EXPRESSION_VALUE: case MACRO_VALUE: // already checked break; default: value.getLocation().reportSemanticError(BMPSTRINGVALUEEXPECTED); value.setIsErroneous(true); } }
@Override public IValue evaluateValue( final CompilationTimeStamp timestamp, final Expected_Value_type expectedValue, final IReferenceChain referenceChain) { if (lastTimeChecked != null && !lastTimeChecked.isLess(timestamp)) { return lastValue; } isErroneous = false; lastTimeChecked = timestamp; lastValue = this; if (value == null) { return lastValue; } checkExpressionOperands(timestamp, expectedValue, referenceChain); if (getIsErroneous(timestamp) || isUnfoldable(timestamp, referenceChain)) { return lastValue; } IValue last = value.getValueRefdLast(timestamp, referenceChain); if (last.getIsErroneous(timestamp)) { return lastValue; } switch (last.getValuetype()) { case CHARSTRING_VALUE: { String string = ((Charstring_Value) last).getValue(); string = string.trim(); double number; if ("-INF".equals(string)) { number = Float.NEGATIVE_INFINITY; } else if ("INF".equals(string)) { number = Float.POSITIVE_INFINITY; } else { try { number = Double.parseDouble(string); } catch (NumberFormatException e) { number = 0; } } lastValue = new Real_Value(number); break; } default: return this; } lastValue.copyGeneralProperties(this); return lastValue; }
/** * Checks the parameters of the expression and if they are valid in their position in the * expression or not. * * @param timestamp the timestamp of the actual semantic check cycle. * @param expectedValue the kind of value expected. * @param referenceChain a reference chain to detect cyclic references. */ private void checkExpressionOperands( final CompilationTimeStamp timestamp, final Expected_Value_type expectedValue, final IReferenceChain referenceChain) { if (value1 == null || value2 == null) { return; } IValue last1 = null; IValue last2 = null; Integer_Value i1 = new Integer_Value(0); value1.setLoweridToReference(timestamp); Type_type tempType1 = value1.getExpressionReturntype(timestamp, expectedValue); switch (tempType1) { case TYPE_INTEGER: last1 = value1.getValueRefdLast(timestamp, expectedValue, referenceChain); if (!last1.isUnfoldable(timestamp) && Value.Value_type.INTEGER_VALUE.equals(last1.getValuetype())) { i1 = (Integer_Value) last1; if (i1.signum() < 0) { value1.getLocation().reportSemanticError(OPERANDERROR2); setIsErroneous(true); } } break; case TYPE_UNDEFINED: setIsErroneous(true); break; default: if (!isErroneous) { location.reportSemanticError(OPERANDERROR1); setIsErroneous(true); } break; } value2.setLoweridToReference(timestamp); Type_type tempType2 = value2.getExpressionReturntype(timestamp, expectedValue); switch (tempType2) { case TYPE_INTEGER: last2 = value2.getValueRefdLast(timestamp, expectedValue, referenceChain); if (!last2.isUnfoldable(timestamp) && Value.Value_type.INTEGER_VALUE.equals(last2.getValuetype())) { if (!((Integer_Value) last2).isNative()) { value2.getLocation().reportSemanticError(MessageFormat.format(OPERANDERROR6, last2)); setIsErroneous(true); } else { long i2 = ((Integer_Value) last2).getValue(); if (i2 < 0) { value2.getLocation().reportSemanticError(OPERANDERROR4); setIsErroneous(true); } else if (last1 != null && !last1.isUnfoldable(timestamp) && Value.Value_type.INTEGER_VALUE.equals(last1.getValuetype())) { if ((i1.shiftRight((int) i2 * 8)).signum() > 0) { location.reportSemanticError(MessageFormat.format(OPERANDERROR5, i1, i2)); setIsErroneous(true); } } } } break; case TYPE_UNDEFINED: setIsErroneous(true); break; default: if (!isErroneous) { location.reportSemanticError(OPERANDERROR3); setIsErroneous(true); } break; } }
@Override public IType getFieldType( final CompilationTimeStamp timestamp, final Reference reference, final int actualSubReference, final Expected_Value_type expectedIndex, final IReferenceChain refChain, final boolean interruptIfOptional) { List<ISubReference> subreferences = reference.getSubreferences(); if (subreferences.size() <= actualSubReference) { return this; } Expected_Value_type internalExpectation = expectedIndex == Expected_Value_type.EXPECTED_TEMPLATE ? Expected_Value_type.EXPECTED_DYNAMIC_VALUE : expectedIndex; ISubReference subreference = subreferences.get(actualSubReference); switch (subreference.getReferenceType()) { case arraySubReference: Value indexValue = ((ArraySubReference) subreference).getValue(); if (indexValue != null) { indexValue.setLoweridToReference(timestamp); Type_type tempType = indexValue.getExpressionReturntype(timestamp, expectedIndex); switch (tempType) { case TYPE_INTEGER: IValue last = indexValue.getValueRefdLast(timestamp, expectedIndex, refChain); if (Value_type.INTEGER_VALUE.equals(last.getValuetype())) { Integer_Value lastInteger = (Integer_Value) last; if (lastInteger.isNative()) { long temp = lastInteger.getValue(); if (temp < 0) { indexValue .getLocation() .reportSemanticError(MessageFormat.format(NONNEGATIVINDEXEXPECTED, last)); indexValue.setIsErroneous(true); } } else { indexValue .getLocation() .reportSemanticError( MessageFormat.format(TOOBIGINDEX, indexValue, getTypename())); indexValue.setIsErroneous(true); } } break; case TYPE_UNDEFINED: indexValue.setIsErroneous(true); break; default: indexValue.getLocation().reportSemanticError(INTEGERINDEXEXPECTED); indexValue.setIsErroneous(true); break; } } if (getOfType() != null) { return getOfType() .getFieldType( timestamp, reference, actualSubReference + 1, internalExpectation, refChain, interruptIfOptional); } return null; case fieldSubReference: subreference .getLocation() .reportSemanticError( MessageFormat.format( FieldSubReference.INVALIDSUBREFERENCE, ((FieldSubReference) subreference).getId().getDisplayName(), getTypename())); return null; case parameterisedSubReference: subreference .getLocation() .reportSemanticError( MessageFormat.format( FieldSubReference.INVALIDSUBREFERENCE, ((ParameterisedSubReference) subreference).getId().getDisplayName(), getTypename())); return null; default: subreference.getLocation().reportSemanticError(ISubReference.INVALIDSUBREFERENCE); return null; } }
@Override public void checkThisTemplate( final CompilationTimeStamp timestamp, final ITTCN3Template template, final boolean isModified, final boolean implicitOmit) { registerUsage(template); template.setMyGovernor(this); switch (template.getTemplatetype()) { case OMIT_VALUE: if (template.getLengthRestriction() != null) { template.getLocation().reportSemanticWarning(REDUNDANTLENGTHRESTRICTION); } break; case PERMUTATION_MATCH: { PermutationMatch_Template permutationTemplate = (PermutationMatch_Template) template; int nofComponents = permutationTemplate.getNofTemplates(); for (int i = 0; i < nofComponents; i++) { ITTCN3Template templateComponent = permutationTemplate.getTemplateByIndex( i); // FIXME: type is ok? It should be ITemplateListItem! templateComponent.setMyGovernor(getOfType()); templateComponent = getOfType() .checkThisTemplateRef( timestamp, templateComponent); // It does not do anything for AllElementsFrom, it is ok templateComponent.checkThisTemplateGeneric( timestamp, getOfType(), false, false, true, true, implicitOmit); // it is a special for AllElementsFrom, it is the usual for // TemplateBody } break; } case SUPERSET_MATCH: { SupersetMatch_Template supersetTemplate = (SupersetMatch_Template) template; int nofComponents = supersetTemplate.getNofTemplates(); for (int i = 0; i < nofComponents; i++) { ITTCN3Template templateComponent = supersetTemplate.getTemplateByIndex( i); // FIXME: type is ok? It should be ITemplateListItem! templateComponent.setMyGovernor(getOfType()); templateComponent = getOfType() .checkThisTemplateRef( timestamp, templateComponent); // It does not do anything for AllElementsFrom, it is ok templateComponent.checkThisTemplateGeneric( timestamp, getOfType(), false, false, true, true, implicitOmit); // it is a special for AllElementsFrom, it is the usual for // TemplateBody } break; } case SUBSET_MATCH: { SubsetMatch_Template subsetTemplate = (SubsetMatch_Template) template; int nofComponents = subsetTemplate.getNofTemplates(); for (int i = 0; i < nofComponents; i++) { ITTCN3Template templateComponent = subsetTemplate.getTemplateByIndex( i); // FIXME: type is ok? It should be ITemplateListItem! templateComponent.setMyGovernor(getOfType()); templateComponent = getOfType() .checkThisTemplateRef( timestamp, templateComponent); // It does not do anything for AllElementsFrom, it is ok templateComponent.checkThisTemplateGeneric( timestamp, getOfType(), false, false, true, true, implicitOmit); // it is a special for AllElementsFrom, it is the usual for // TemplateBody } break; } case TEMPLATE_LIST: { Completeness_type completeness = template.getCompletenessConditionSeof(timestamp, isModified); Template_List base = null; int nofBaseComps = 0; if (Completeness_type.PARTIAL.equals(completeness)) { ITTCN3Template tempBase = template.getBaseTemplate(); if (tempBase != null) { tempBase = tempBase.getTemplateReferencedLast(timestamp); } if (tempBase == null) { setIsErroneous(true); return; } base = ((Template_List) tempBase); nofBaseComps = base.getNofTemplates(); } Template_List templateList = (Template_List) template; int nofComponents = templateList.getNofTemplates(); for (int i = 0; i < nofComponents; i++) { ITTCN3Template component = templateList.getTemplateByIndex(i); component.setMyGovernor(getOfType()); if (base != null && nofBaseComps > i) { component.setBaseTemplate(base.getTemplateByIndex(i)); } else { component.setBaseTemplate(null); } component = getOfType().checkThisTemplateRef(timestamp, component); switch (component.getTemplatetype()) { case PERMUTATION_MATCH: case SUPERSET_MATCH: case SUBSET_MATCH: // FIXME: for Complement??? case COMPLEMENTED_LIST: ??? // the elements of permutation has to be checked by u.seof.ofType // the templates within the permutation always have to be complete component.checkThisTemplateGeneric( timestamp, this, false, false, true, true, implicitOmit); break; case TEMPLATE_NOTUSED: if (Completeness_type.MUST_COMPLETE.equals(completeness)) { component.getLocation().reportSemanticError(NOTUSEDNOTALLOWED1); } else if (Completeness_type.PARTIAL.equals(completeness) && i >= nofBaseComps) { component.getLocation().reportSemanticError(NOTUSEDNOTALLOWED2); } break; default: boolean embeddedModified = (completeness == Completeness_type.MAY_INCOMPLETE) || (completeness == Completeness_type.PARTIAL && i < nofBaseComps); component.checkThisTemplateGeneric( timestamp, getOfType(), embeddedModified, false, true, true, implicitOmit); break; } } break; } case INDEXED_TEMPLATE_LIST: { Map<Long, Integer> indexMap = new HashMap<Long, Integer>(); Indexed_Template_List indexedTemplateList = (Indexed_Template_List) template; for (int i = 0, size = indexedTemplateList.getNofTemplates(); i < size; i++) { IndexedTemplate indexedTemplate = indexedTemplateList.getIndexedTemplateByIndex(i); Value indexValue = indexedTemplate.getIndex().getValue(); ITTCN3Template templateComponent = indexedTemplate.getTemplate(); IReferenceChain chain = ReferenceChain.getInstance(IReferenceChain.CIRCULARREFERENCE, true); IValue lastValue = indexValue.getValueRefdLast(timestamp, chain); chain.release(); if (Value_type.INTEGER_VALUE.equals(lastValue.getValuetype())) { long index = ((Integer_Value) lastValue).getValue(); if (index > Integer.MAX_VALUE) { indexValue .getLocation() .reportSemanticError( MessageFormat.format( TOOBIGINDEXTEMPLATE, Integer.MAX_VALUE, getTypename(), index)); indexValue.setIsErroneous(true); } else if (index < 0) { indexValue .getLocation() .reportSemanticError( MessageFormat.format( NONNEGATIVEINDEXEXPECTEDTEMPLATE, getTypename(), index)); indexValue.setIsErroneous(true); } else { if (indexMap.containsKey(index)) { indexValue .getLocation() .reportSemanticError( MessageFormat.format(DUPLICATEINDEX, index, i + 1, indexMap.get(index))); indexValue.setIsErroneous(true); } else { indexMap.put(index, i); } } } else { indexValue.getLocation().reportSemanticError(INTEGERINDEXEXPECTED); indexValue.setIsErroneous(true); } templateComponent.setMyGovernor(getOfType()); templateComponent = getOfType().checkThisTemplateRef(timestamp, templateComponent); templateComponent.checkThisTemplateGeneric( timestamp, getOfType(), true, false, true, true, implicitOmit); } break; } default: template .getLocation() .reportSemanticError( MessageFormat.format( TEMPLATENOTALLOWED, template.getTemplateTypeName(), getTypename())); break; } }
/** * Checks the SequenceOf_value kind value against this type. * * <p>Please note, that this function can only be called once we know for sure that the value is * of set-of type. * * @param timestamp the timestamp of the actual semantic check cycle. * @param value the value to be checked * @param expectedValue the kind of value expected here. * @param incompleteAllowed wheather incomplete value is allowed or not. * @param implicit_omit true if the implicit omit optional attribute was set for the value, false * otherwise */ public void checkThisValueSequenceOf( final CompilationTimeStamp timestamp, final SequenceOf_Value value, final Expected_Value_type expectedValue, final boolean incompleteAllowed, final boolean implicit_omit, final boolean strElem) { if (value.isIndexed()) { boolean checkHoles = Expected_Value_type.EXPECTED_CONSTANT.equals(expectedValue); BigInteger maxIndex = BigInteger.valueOf(-1); Map<BigInteger, Integer> indexMap = new HashMap<BigInteger, Integer>(value.getNofComponents()); for (int i = 0, size = value.getNofComponents(); i < size; i++) { IValue component = value.getValueByIndex(i); IValue index = value.getIndexByIndex(i); IReferenceChain referenceChain = ReferenceChain.getInstance(IReferenceChain.CIRCULARREFERENCE, true); IValue indexLast = index.getValueRefdLast(timestamp, referenceChain); referenceChain.release(); if (indexLast.getIsErroneous(timestamp) || !Value_type.INTEGER_VALUE.equals(indexLast.getValuetype())) { checkHoles = false; } else { BigInteger tempIndex = ((Integer_Value) indexLast).getValueValue(); if (tempIndex.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 1) { index .getLocation() .reportSemanticError( MessageFormat.format( "A integer value less than `{0}'' was expected for indexing type `{1}'' instead of `{2}''", Integer.MAX_VALUE, getTypename(), tempIndex)); checkHoles = false; } else if (tempIndex.compareTo(BigInteger.ZERO) == -1) { index .getLocation() .reportSemanticError( MessageFormat.format( "A non-negative integer value was expected for indexing type `{0}'' instead of `{1}''", getTypename(), tempIndex)); checkHoles = false; } else if (indexMap.containsKey(tempIndex)) { index .getLocation() .reportSemanticError( MessageFormat.format( "Duplicate index value `{0}'' for components {1} and {2}", tempIndex, indexMap.get(tempIndex), i + 1)); checkHoles = false; } else { indexMap.put(tempIndex, Integer.valueOf(i + 1)); if (maxIndex.compareTo(tempIndex) == -1) { maxIndex = tempIndex; } } } component.setMyGovernor(getOfType()); IValue tempValue2 = getOfType().checkThisValueRef(timestamp, component); getOfType() .checkThisValue( timestamp, tempValue2, new ValueCheckingOptions( expectedValue, incompleteAllowed, false, true, implicit_omit, strElem)); } if (checkHoles) { if (maxIndex.compareTo(BigInteger.valueOf(indexMap.size() - 1)) != 0) { value .getLocation() .reportSemanticError("It's not allowed to create hole(s) in constant values"); } } } else { for (int i = 0, size = value.getNofComponents(); i < size; i++) { IValue component = value.getValueByIndex(i); component.setMyGovernor(getOfType()); if (Value_type.NOTUSED_VALUE.equals(component.getValuetype())) { if (!incompleteAllowed) { component.getLocation().reportSemanticError(INCOMPLETEPRESENTERROR); } } else { IValue tempValue2 = getOfType().checkThisValueRef(timestamp, component); getOfType() .checkThisValue( timestamp, tempValue2, new ValueCheckingOptions( expectedValue, incompleteAllowed, false, true, implicit_omit, strElem)); } } } }
@Override public void checkThisValue( final CompilationTimeStamp timestamp, final IValue value, final ValueCheckingOptions valueCheckingOptions) { if (getIsErroneous(timestamp)) { return; } super.checkThisValue(timestamp, value, valueCheckingOptions); IValue last = value.getValueRefdLast(timestamp, valueCheckingOptions.expected_value, null); if (last == null || last.getIsErroneous(timestamp)) { return; } // already handled ones switch (value.getValuetype()) { case OMIT_VALUE: case REFERENCED_VALUE: return; case UNDEFINED_LOWERIDENTIFIER_VALUE: if (Value_type.REFERENCED_VALUE.equals(last.getValuetype())) { return; } break; default: break; } if (Value_type.UNDEFINED_BLOCK.equals(last.getValuetype())) { last = last.setValuetype(timestamp, Value_type.SEQUENCEOF_VALUE); } if (last.getIsErroneous(timestamp)) { return; } switch (last.getValuetype()) { case SEQUENCEOF_VALUE: { checkThisValueSequenceOf( timestamp, (SequenceOf_Value) last, valueCheckingOptions.expected_value, valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit, valueCheckingOptions.str_elem); break; } case SETOF_VALUE: { checkThisValueSetOf( timestamp, (SetOf_Value) last, valueCheckingOptions.expected_value, valueCheckingOptions.incomplete_allowed, valueCheckingOptions.implicit_omit, valueCheckingOptions.str_elem); break; } case EXPRESSION_VALUE: case MACRO_VALUE: // already checked break; default: if (value.isAsn()) { value.getLocation().reportSemanticError(SEQOFVALUEEXPECTED); } else { value.getLocation().reportSemanticError(RECORDOFVALUEEXPECTED); } value.setIsErroneous(true); } if (valueCheckingOptions.sub_check) { // there is no parent type to check if (subType != null) { subType.checkThisValue(timestamp, last); } } }