Search in sources :

Example 1 with Qualifier

use of org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier in project titan.EclipsePlug-ins by eclipse.

the class Type method checkVariants.

/**
 * Checks the type's variant attributes (when using the new codec handling).
 */
public void checkVariants(final CompilationTimeStamp timestamp) {
    if (isAsn() || ownerType != TypeOwner_type.OT_TYPE_DEF) {
        return;
    }
    WithAttributesPath globalAttributesPath;
    final Def_Type def = (Def_Type) owner;
    final Group nearest_group = def.getParentGroup();
    if (nearest_group == null) {
        // no group, use the module
        Module myModule = myScope.getModuleScope();
        globalAttributesPath = ((TTCN3Module) myModule).getAttributePath();
    } else {
        globalAttributesPath = nearest_group.getAttributePath();
    }
    if (globalAttributesPath != null) {
        // process all global variants, not just the closest group
        final List<SingleWithAttribute> realAttributes = globalAttributesPath.getRealAttributes(timestamp);
        for (int i = 0; i < realAttributes.size(); i++) {
            final SingleWithAttribute singleWithAttribute = realAttributes.get(i);
            if (singleWithAttribute.getAttributeType() == Attribute_Type.Variant_Attribute) {
                checkThisVariant(timestamp, singleWithAttribute, true);
            }
        }
    }
    // check local variant attributes second, so they overwrite global ones if they
    // conflict with each other
    final WithAttributesPath attributePath = getAttributePath();
    if (attributePath != null) {
        final MultipleWithAttributes multipleWithAttributes = attributePath.getAttributes();
        if (multipleWithAttributes != null) {
            for (int i = 0; i < multipleWithAttributes.getNofElements(); i++) {
                final SingleWithAttribute singleWithAttribute = multipleWithAttributes.getAttribute(i);
                if (singleWithAttribute.getAttributeType() == Attribute_Type.Variant_Attribute) {
                    final Qualifiers qualifiers = singleWithAttribute.getQualifiers();
                    if (qualifiers != null && qualifiers.getNofQualifiers() > 0) {
                        for (int j = 0; j < qualifiers.getNofQualifiers(); j++) {
                            final Qualifier qualifier = qualifiers.getQualifierByIndex(j);
                            final List<ISubReference> fieldsOrArrays = new ArrayList<ISubReference>();
                            for (int k = 0; k < qualifier.getNofSubReferences(); k++) {
                                fieldsOrArrays.add(qualifier.getSubReferenceByIndex(k));
                            }
                            final Reference reference = new Reference(null, fieldsOrArrays);
                            final IType type = getFieldType(timestamp, reference, 0, Expected_Value_type.EXPECTED_CONSTANT, false);
                            if (type != null) {
                                if (type.getMyScope() != myScope) {
                                    qualifier.getLocation().reportSemanticWarning("Variant attribute is ignored, because it refers to a type from a different type definition");
                                } else {
                                    type.checkThisVariant(timestamp, singleWithAttribute, false);
                                }
                            }
                        }
                    } else {
                        checkThisVariant(timestamp, singleWithAttribute, false);
                    }
                }
            }
        }
    }
    // check the coding attributes set by the variants
    final IReferenceChain chain = ReferenceChain.getInstance(IReferenceChain.CIRCULARREFERENCE, true);
    checkCodingAttributes(timestamp, chain);
    chain.release();
}
Also used : WithAttributesPath(org.eclipse.titan.designer.AST.TTCN3.attributes.WithAttributesPath) Group(org.eclipse.titan.designer.AST.TTCN3.definitions.Group) Def_Type(org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Type) ArrayList(java.util.ArrayList) SingleWithAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute) MultipleWithAttributes(org.eclipse.titan.designer.AST.TTCN3.attributes.MultipleWithAttributes) Qualifier(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier) Qualifiers(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifiers) TTCN3Module(org.eclipse.titan.designer.AST.TTCN3.definitions.TTCN3Module)

Example 2 with Qualifier

use of org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier in project titan.EclipsePlug-ins by eclipse.

the class Definition method checkErroneousAttributes.

protected void checkErroneousAttributes(final CompilationTimeStamp timestamp) {
    erroneousAttributes = null;
    if (withAttributesPath != null) {
        final MultipleWithAttributes attribs = withAttributesPath.getAttributes();
        if (attribs == null) {
            return;
        }
        for (int i = 0; i < attribs.getNofElements(); i++) {
            final SingleWithAttribute actualAttribute = attribs.getAttribute(i);
            if (actualAttribute.getAttributeType() == Attribute_Type.Erroneous_Attribute) {
                final int nofQualifiers = (actualAttribute.getQualifiers() == null) ? 0 : actualAttribute.getQualifiers().getNofQualifiers();
                final List<IType> referencedTypeArray = new ArrayList<IType>(nofQualifiers);
                final List<ArrayList<Integer>> subrefsArrayArray = new ArrayList<ArrayList<Integer>>(nofQualifiers);
                final List<ArrayList<IType>> typeArrayArray = new ArrayList<ArrayList<IType>>(nofQualifiers);
                if (nofQualifiers == 0) {
                    actualAttribute.getLocation().reportSemanticError("At least one qualifier must be specified for the `erroneous' attribute");
                } else {
                    // existing fields
                    for (int qi = 0; qi < nofQualifiers; qi++) {
                        final Qualifier actualQualifier = actualAttribute.getQualifiers().getQualifierByIndex(qi);
                        final IType definitionType = getType(timestamp);
                        // construct a reference
                        final Reference reference = new Reference(null);
                        reference.addSubReference(new FieldSubReference(identifier));
                        for (int ri = 0; ri < actualQualifier.getNofSubReferences(); ri++) {
                            reference.addSubReference(actualQualifier.getSubReferenceByIndex(ri));
                        }
                        reference.setLocation(actualQualifier.getLocation());
                        reference.setMyScope(getMyScope());
                        IType fieldType = definitionType.getFieldType(timestamp, reference, 1, Expected_Value_type.EXPECTED_CONSTANT, false);
                        ArrayList<Integer> subrefsArray = null;
                        ArrayList<IType> typeArray = null;
                        if (fieldType != null) {
                            subrefsArray = new ArrayList<Integer>();
                            typeArray = new ArrayList<IType>();
                            final boolean validIndexes = definitionType.getSubrefsAsArray(timestamp, reference, 1, subrefsArray, typeArray);
                            if (!validIndexes) {
                                fieldType = null;
                                subrefsArray = null;
                                typeArray = null;
                            }
                            if (reference.refersToStringElement()) {
                                actualQualifier.getLocation().reportSemanticError("Reference to a string element cannot be used in this context");
                                fieldType = null;
                                subrefsArray = null;
                                typeArray = null;
                            }
                        }
                        referencedTypeArray.add(fieldType);
                        subrefsArrayArray.add(subrefsArray);
                        typeArrayArray.add(typeArray);
                    }
                }
                // parse the attr. spec.
                final ErroneousAttributeSpecification errAttributeSpecification = parseErrAttrSpecString(actualAttribute.getAttributeSpecification());
                if (errAttributeSpecification != null) {
                    if (erroneousAttributes == null) {
                        erroneousAttributes = new ErroneousAttributes(getType(timestamp));
                    }
                    erroneousAttributes.addSpecification(errAttributeSpecification);
                    errAttributeSpecification.check(timestamp, getMyScope());
                    // err.attr.spec. pairs
                    for (int qi = 0; qi < nofQualifiers; qi++) {
                        if (referencedTypeArray.get(qi) != null && errAttributeSpecification.getIndicator() != Indicator_Type.Invalid_Indicator) {
                            final Qualifier actualQualifier = actualAttribute.getQualifiers().getQualifierByIndex(qi);
                            erroneousAttributes.addFieldErr(actualQualifier, errAttributeSpecification, subrefsArrayArray.get(qi), typeArrayArray.get(qi));
                        }
                    }
                }
            }
        }
        if (erroneousAttributes != null) {
            erroneousAttributes.check(timestamp);
        }
    }
}
Also used : ErroneousAttributeSpecification(org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributeSpecification) FieldSubReference(org.eclipse.titan.designer.AST.FieldSubReference) FieldSubReference(org.eclipse.titan.designer.AST.FieldSubReference) Reference(org.eclipse.titan.designer.AST.Reference) ArrayList(java.util.ArrayList) ErroneousAttributes(org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributes) SingleWithAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute) MultipleWithAttributes(org.eclipse.titan.designer.AST.TTCN3.attributes.MultipleWithAttributes) IType(org.eclipse.titan.designer.AST.IType) Qualifier(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier)

Example 3 with Qualifier

use of org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier in project titan.EclipsePlug-ins by eclipse.

the class Def_Type method analyzeExtensionAttributes.

/**
 * Convert and check the encoding attributes applied to this function.
 *
 * @param timestamp
 *                the timestamp of the actual build cycle.
 */
public void analyzeExtensionAttributes(final CompilationTimeStamp timestamp, final WithAttributesPath withAttributesPath) {
    final List<SingleWithAttribute> realAttributes = withAttributesPath.getRealAttributes(timestamp);
    SingleWithAttribute attribute;
    List<AttributeSpecification> specifications = null;
    for (int i = 0, size = realAttributes.size(); i < size; i++) {
        attribute = realAttributes.get(i);
        if (Attribute_Type.Extension_Attribute.equals(attribute.getAttributeType())) {
            final Qualifiers qualifiers = attribute.getQualifiers();
            if (qualifiers == null || qualifiers.getNofQualifiers() == 0) {
                if (specifications == null) {
                    specifications = new ArrayList<AttributeSpecification>();
                }
                specifications.add(attribute.getAttributeSpecification());
            } else {
                for (int j = 0, size2 = qualifiers.getNofQualifiers(); j < size2; j++) {
                    final Qualifier tempQualifier = qualifiers.getQualifierByIndex(i);
                    final ISubReference tempSubReference = tempQualifier.getSubReferenceByIndex(0);
                    if (tempSubReference.getReferenceType() == Subreference_type.arraySubReference) {
                        tempQualifier.getLocation().reportSemanticError(Qualifier.INVALID_INDEX_QUALIFIER);
                    } else {
                        tempQualifier.getLocation().reportSemanticError(MessageFormat.format(Qualifier.INVALID_FIELD_QUALIFIER, tempSubReference.getId().getDisplayName()));
                    }
                }
            }
        }
    }
    if (specifications == null) {
        return;
    }
    final List<ExtensionAttribute> attributes = new ArrayList<ExtensionAttribute>();
    for (int i = 0; i < specifications.size(); i++) {
        final AttributeSpecification specification = specifications.get(i);
        final ExtensionAttributeAnalyzer analyzer = new ExtensionAttributeAnalyzer();
        analyzer.parse(specification);
        final List<ExtensionAttribute> temp = analyzer.getAttributes();
        if (temp != null) {
            attributes.addAll(temp);
        }
    }
    for (int i = 0; i < attributes.size(); i++) {
        final ExtensionAttribute extensionAttribute = attributes.get(i);
        switch(extensionAttribute.getAttributeType()) {
            case ANYTYPE:
            case VERSION:
            case REQUIRES:
            case TITANVERSION:
                break;
            default:
                // only extension attributes are allowed ... and
                // only because they can not be stopped earlier.
                extensionAttribute.getLocation().reportSemanticError("Extension attributes are not supported for types");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) SingleWithAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute) ExtensionAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.ExtensionAttribute) ISubReference(org.eclipse.titan.designer.AST.ISubReference) AttributeSpecification(org.eclipse.titan.designer.AST.TTCN3.attributes.AttributeSpecification) ExtensionAttributeAnalyzer(org.eclipse.titan.designer.parsers.extensionattributeparser.ExtensionAttributeAnalyzer) Qualifier(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier) Qualifiers(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifiers)

Example 4 with Qualifier

use of org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier in project titan.EclipsePlug-ins by eclipse.

the class ErroneousAttributes method buildErroneousDescriptorTree.

private ErroneousDescriptor buildErroneousDescriptorTree(final CompilationTimeStamp timestamp, final List<FieldErr_Type> fldArray, final int level) {
    final ErroneousDescriptor erroneousDescr = new ErroneousDescriptor();
    Qualifier omitBeforeQualifier = null;
    Qualifier omitAfterQualifier = null;
    final Map<Integer, List<FieldErr_Type>> embeddedFieldArrayMap = new HashMap<Integer, List<FieldErr_Type>>();
    for (FieldErr_Type actualFieldErr : fldArray) {
        if (actualFieldErr.subrefsArray.size() <= level) {
            ErrorReporter.INTERNAL_ERROR();
            return erroneousDescr;
        }
        final int fieldIndex = actualFieldErr.subrefsArray.get(level);
        final IType fieldType = actualFieldErr.typeArray.get(level);
        if (omitBeforeQualifier != null && erroneousDescr.omitBefore != -1 && erroneousDescr.omitBefore > fieldIndex) {
            final String message = MessageFormat.format("Field `{0}'' cannot be referenced because all fields before field `{1}'' have been omitted", actualFieldErr.qualifier.getDisplayName(), omitBeforeQualifier.getDisplayName());
            actualFieldErr.qualifier.getLocation().reportSemanticError(message);
            continue;
        }
        if (omitAfterQualifier != null && erroneousDescr.omitAfter != -1 && erroneousDescr.omitAfter < fieldIndex) {
            final String message = MessageFormat.format("Field `{0}'' cannot be referenced because all fields after field `{1}'' have been omitted", actualFieldErr.qualifier.getDisplayName(), omitAfterQualifier.getDisplayName());
            actualFieldErr.qualifier.getLocation().reportSemanticError(message);
            continue;
        }
        final Indicator_Type actIndicator = actualFieldErr.errAttrSpec.getIndicator();
        final boolean isOmit = actualFieldErr.errAttrSpec.isOmit();
        if (actualFieldErr.subrefsArray.size() == level + 1) {
            // erroneous value
            if (actualFieldErr.typeArray.size() != level + 1) {
                ErrorReporter.INTERNAL_ERROR();
                return erroneousDescr;
            }
            if (fieldType.getTypetype() == Type_type.TYPE_ASN1_SET && isOmit && actIndicator != Indicator_Type.Value_Indicator) {
                final String message = MessageFormat.format("Cannot omit all fields {0} `{1}'' which is a field of an ASN.1 SET type. " + "The order of fields in ASN.1 SET types changes depending on tagging (see X.690 9.3). " + "Fields can be omitted individually, independently of the field order which depends on tagging", actIndicator.getDisplayName(), actualFieldErr.qualifier.getDisplayName());
                actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                continue;
            }
            switch(fieldType.getTypetypeTtcn3()) {
                case TYPE_TTCN3_CHOICE:
                    if (actIndicator != Indicator_Type.Value_Indicator) {
                        final String message = MessageFormat.format("Indicator `{0}'' cannot be used with reference `{1}'' which points to a field of a union type", actIndicator.getDisplayName(), actualFieldErr.qualifier.getDisplayName());
                        actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                        continue;
                    }
                    break;
                case TYPE_TTCN3_SEQUENCE:
                case TYPE_TTCN3_SET:
                    if (isOmit && actIndicator == Indicator_Type.After_Indicator) {
                        int lastFieldIndex;
                        switch(fieldType.getTypetype()) {
                            case TYPE_ASN1_SEQUENCE:
                                lastFieldIndex = ((ASN1_Sequence_Type) fieldType).getNofComponents(timestamp) - 1;
                                break;
                            case TYPE_ASN1_SET:
                                lastFieldIndex = ((ASN1_Set_Type) fieldType).getNofComponents(timestamp) - 1;
                                break;
                            default:
                                lastFieldIndex = ((TTCN3_Set_Seq_Choice_BaseType) fieldType).getNofComponents() - 1;
                        }
                        if (fieldIndex == lastFieldIndex) {
                            final String message = MessageFormat.format("There is nothing to omit after the last field ({0}) of a record/set type", actualFieldErr.qualifier.getDisplayName());
                            actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                            continue;
                        }
                    }
                // $FALL-THROUGH$
                case TYPE_SEQUENCE_OF:
                case TYPE_SET_OF:
                    if (isOmit && actIndicator == Indicator_Type.Before_Indicator && fieldIndex == 0) {
                        actualFieldErr.qualifier.getLocation().reportSemanticError(MessageFormat.format("There is nothing to omit before the first field ({0})", actualFieldErr.qualifier.getDisplayName()));
                        continue;
                    }
                    break;
                default:
                    break;
            }
            // check for duplicate value+indicator
            if (erroneousDescr.valuesMap.containsKey(fieldIndex)) {
                final ErroneousValues evs = erroneousDescr.valuesMap.get(fieldIndex);
                if ((evs.before != null && actIndicator == Indicator_Type.Before_Indicator) || (evs.value != null && actIndicator == Indicator_Type.Value_Indicator) || (evs.after != null && actIndicator == Indicator_Type.After_Indicator)) {
                    actualFieldErr.qualifier.getLocation().reportSemanticError(MessageFormat.format("Duplicate reference to field `{0}'' with indicator `{1}''", actualFieldErr.qualifier.getDisplayName(), actIndicator.getDisplayName()));
                    continue;
                }
            }
            // values were used
            if (actIndicator == Indicator_Type.Value_Indicator && embeddedFieldArrayMap.containsKey(fieldIndex)) {
                final String message = MessageFormat.format("Reference to field `{0}'' with indicator `value'' would invalidate previously specified erroneous data", actualFieldErr.qualifier.getDisplayName());
                actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                continue;
            }
            // duplication of omit before/after rule
            if (actIndicator == Indicator_Type.Before_Indicator && isOmit) {
                if (omitBeforeQualifier != null && erroneousDescr.omitBefore != -1) {
                    final String message = MessageFormat.format("Duplicate rule for omitting all fields before the specified field. " + "Used on field `{0}'' but previously already used on field `{1}''", actualFieldErr.qualifier.getDisplayName(), omitBeforeQualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                boolean isInvalid = false;
                for (Integer idx : erroneousDescr.valuesMap.keySet()) {
                    if (idx < fieldIndex) {
                        isInvalid = true;
                        break;
                    }
                }
                if (!isInvalid) {
                    for (Integer idx : embeddedFieldArrayMap.keySet()) {
                        if (idx < fieldIndex) {
                            isInvalid = true;
                            break;
                        }
                    }
                }
                if (isInvalid) {
                    final String message = MessageFormat.format("Omitting fields before field `{0}'' would invalidate previously specified erroneous data", actualFieldErr.qualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                // save valid omit before data
                omitBeforeQualifier = actualFieldErr.qualifier;
                erroneousDescr.omitBefore = fieldIndex;
                erroneousDescr.omitBeforeName = omitBeforeQualifier.getDisplayName();
                continue;
            }
            if (actIndicator == Indicator_Type.After_Indicator && isOmit) {
                if (omitAfterQualifier != null && erroneousDescr.omitAfter != -1) {
                    final String message = MessageFormat.format("Duplicate rule for omitting all fields after the specified field. " + "Used on field `{0}'' but previously already used on field `{1}''", actualFieldErr.qualifier.getDisplayName(), omitAfterQualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                boolean isInvalid = false;
                for (Integer idx : erroneousDescr.valuesMap.keySet()) {
                    if (idx > fieldIndex) {
                        isInvalid = true;
                        break;
                    }
                }
                if (!isInvalid) {
                    for (Integer idx : embeddedFieldArrayMap.keySet()) {
                        if (idx > fieldIndex) {
                            isInvalid = true;
                            break;
                        }
                    }
                }
                if (isInvalid) {
                    final String message = MessageFormat.format("Omitting fields after field `{0}'' would invalidate previously specified erroneous data", actualFieldErr.qualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                // save valid omit after data
                omitAfterQualifier = actualFieldErr.qualifier;
                erroneousDescr.omitAfter = fieldIndex;
                erroneousDescr.omitAfterName = omitAfterQualifier.getDisplayName();
                continue;
            }
            // if not before/after omit then save this into
            // values_m
            final boolean hasKey = erroneousDescr.valuesMap.containsKey(fieldIndex);
            final ErroneousValues evs = hasKey ? erroneousDescr.valuesMap.get(fieldIndex) : new ErroneousValues(actualFieldErr.qualifier.getDisplayName());
            switch(actIndicator) {
                case Before_Indicator:
                    evs.before = actualFieldErr.errAttrSpec;
                    break;
                case Value_Indicator:
                    evs.value = actualFieldErr.errAttrSpec;
                    break;
                case After_Indicator:
                    evs.after = actualFieldErr.errAttrSpec;
                    break;
                default:
                    ErrorReporter.INTERNAL_ERROR();
            }
            if (!hasKey) {
                erroneousDescr.valuesMap.put(fieldIndex, evs);
            }
        } else {
            // embedded err.value
            if (erroneousDescr.valuesMap.containsKey(fieldIndex) && erroneousDescr.valuesMap.get(fieldIndex).value != null) {
                final String message = MessageFormat.format("Field `{0}'' is embedded into a field which was previously overwritten or omitted", actualFieldErr.qualifier.getDisplayName());
                actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                continue;
            }
            // add the embedded field to the map
            final boolean hasIndex = embeddedFieldArrayMap.containsKey(fieldIndex);
            final List<FieldErr_Type> embeddedFieldArray = hasIndex ? embeddedFieldArrayMap.get(fieldIndex) : new ArrayList<FieldErr_Type>(1);
            embeddedFieldArray.add(actualFieldErr);
            if (!hasIndex) {
                embeddedFieldArrayMap.put(fieldIndex, embeddedFieldArray);
            }
        }
    }
    // recursive calls to create embedded descriptors
    for (Integer idx : embeddedFieldArrayMap.keySet()) {
        erroneousDescr.descriptorMap.put(idx, buildErroneousDescriptorTree(timestamp, embeddedFieldArrayMap.get(idx), level + 1));
    }
    return erroneousDescr;
}
Also used : HashMap(java.util.HashMap) ASN1_Set_Type(org.eclipse.titan.designer.AST.ASN1.types.ASN1_Set_Type) IType(org.eclipse.titan.designer.AST.IType) Indicator_Type(org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributeSpecification.Indicator_Type) ASN1_Sequence_Type(org.eclipse.titan.designer.AST.ASN1.types.ASN1_Sequence_Type) ArrayList(java.util.ArrayList) List(java.util.List) TTCN3_Set_Seq_Choice_BaseType(org.eclipse.titan.designer.AST.TTCN3.types.TTCN3_Set_Seq_Choice_BaseType)

Example 5 with Qualifier

use of org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier in project titan.EclipsePlug-ins by eclipse.

the class Type method checkEncode.

/**
 * Checks the encodings supported by the type (when using new codec handling).
 * TTCN-3 types need to have an 'encode' attribute to support an encoding.
 * ASN.1 types automatically support BER, PER and JSON encodings, and XER
 * encoding, if set by the compiler option.
 */
public void checkEncode(final CompilationTimeStamp timestamp) {
    switch(getTypeRefdLast(timestamp).getTypetypeTtcn3()) {
        case TYPE_NULL:
        case TYPE_BOOL:
        case TYPE_INTEGER:
        case TYPE_REAL:
        case TYPE_TTCN3_ENUMERATED:
        case TYPE_BITSTRING:
        case TYPE_HEXSTRING:
        case TYPE_OCTETSTRING:
        case TYPE_CHARSTRING:
        case TYPE_UCHARSTRING:
        case TYPE_OBJECTID:
        case TYPE_TTCN3_CHOICE:
        case TYPE_SEQUENCE_OF:
        case TYPE_SET_OF:
        case TYPE_TTCN3_SEQUENCE:
        case TYPE_TTCN3_SET:
        case TYPE_VERDICT:
        case TYPE_ARRAY:
        case TYPE_ANYTYPE:
            if (!isAsn()) {
                final WithAttributesPath attributePath = getAttributePath();
                if (attributePath != null) {
                    final MultipleWithAttributes multipleWithAttributes = attributePath.getAttributes();
                    if (multipleWithAttributes != null) {
                        for (int i = 0; i < multipleWithAttributes.getNofElements(); i++) {
                            final SingleWithAttribute singleWithAttribute = multipleWithAttributes.getAttribute(i);
                            if (singleWithAttribute.getAttributeType() == Attribute_Type.Encode_Attribute) {
                                final Attribute_Modifier_type mod = singleWithAttribute.getModifier();
                                final Qualifiers qualifiers = singleWithAttribute.getQualifiers();
                                if (qualifiers != null && qualifiers.getNofQualifiers() > 0) {
                                    for (int j = 0; j < qualifiers.getNofQualifiers(); j++) {
                                        final Qualifier qualifier = qualifiers.getQualifierByIndex(j);
                                        final List<ISubReference> fieldsOrArrays = new ArrayList<ISubReference>();
                                        for (int k = 0; k < qualifier.getNofSubReferences(); k++) {
                                            fieldsOrArrays.add(qualifier.getSubReferenceByIndex(k));
                                        }
                                        final Reference reference = new Reference(null, fieldsOrArrays);
                                        final IType type = getFieldType(timestamp, reference, 0, Expected_Value_type.EXPECTED_CONSTANT, false);
                                        if (type != null) {
                                            if (type.getMyScope() != myScope) {
                                                qualifier.getLocation().reportSemanticWarning("Encode attribute is ignored, because it refers to a type from a different type definition");
                                            } else {
                                                type.addCoding(timestamp, singleWithAttribute.getAttributeSpecification().getSpecification(), mod, false);
                                            }
                                        }
                                    }
                                } else {
                                    addCoding(timestamp, singleWithAttribute.getAttributeSpecification().getSpecification(), mod, false);
                                }
                            }
                        }
                    }
                    if (ownerType != TypeOwner_type.OT_TYPE_DEF) {
                        return;
                    }
                    WithAttributesPath globalAttributesPath;
                    final Def_Type def = (Def_Type) owner;
                    final Group nearest_group = def.getParentGroup();
                    if (nearest_group == null) {
                        // no group, use the module
                        Module myModule = myScope.getModuleScope();
                        globalAttributesPath = ((TTCN3Module) myModule).getAttributePath();
                    } else {
                        globalAttributesPath = nearest_group.getAttributePath();
                    }
                    if (globalAttributesPath != null) {
                        boolean hasGlobalOverride = false;
                        boolean modifierConflict = false;
                        Attribute_Modifier_type firstModifier = Attribute_Modifier_type.MOD_NONE;
                        final List<SingleWithAttribute> realAttributes = globalAttributesPath.getRealAttributes(timestamp);
                        for (int i = 0; i < realAttributes.size(); i++) {
                            final SingleWithAttribute singleWithAttribute = realAttributes.get(i);
                            if (singleWithAttribute.getAttributeType() == Attribute_Type.Encode_Attribute) {
                                Attribute_Modifier_type modifier = singleWithAttribute.getModifier();
                                if (i == 0) {
                                    firstModifier = modifier;
                                } else if (!modifierConflict && modifier != firstModifier) {
                                    modifierConflict = true;
                                    singleWithAttribute.getLocation().reportSemanticError("All 'encode' attributes of a group or module must have the same modifier ('override', '@local' or none)");
                                }
                                if (modifier == Attribute_Modifier_type.MOD_OVERRIDE) {
                                    hasGlobalOverride = true;
                                }
                                if (hasGlobalOverride && modifierConflict) {
                                    break;
                                }
                            }
                        }
                        // make a list of the type and its field and element types that inherit
                        // the global 'encode' attributes
                        // overriding global attributes are inherited by types with no coding
                        // table (no 'encode' attributes) of their own
                        // non-overriding global attributes are inherited by types that have
                        // no coding table of their own and cannot use the coding table of any
                        // other type
                        final ArrayList<IType> typeList = new ArrayList<IType>();
                        getTypesWithNoCodingTable(timestamp, typeList, hasGlobalOverride);
                        if (!typeList.isEmpty()) {
                            for (int i = 0; i < realAttributes.size(); i++) {
                                final SingleWithAttribute singleWithAttribute = realAttributes.get(i);
                                if (singleWithAttribute.getAttributeType() == Attribute_Type.Encode_Attribute) {
                                    for (int j = typeList.size() - 1; j >= 0; j--) {
                                        typeList.get(j).addCoding(timestamp, singleWithAttribute.getAttributeSpecification().getSpecification(), Attribute_Modifier_type.MOD_NONE, true);
                                    }
                                }
                            }
                            typeList.clear();
                        }
                    }
                }
            } else {
                // ASN.1 types automatically have BER, PER, XER, OER and JSON encoding
                switch(ownerType) {
                    case OT_TYPE_ASS:
                    case OT_RECORD_OF:
                    case OT_COMP_FIELD:
                    case OT_SELTYPE:
                    case OT_FIELDSETTING:
                        // FIXME implement once PER, JSON, OER or XER gets supported
                        break;
                    default:
                        break;
                }
            }
            break;
        default:
            // the rest of the types can't have 'encode' attributes
            break;
    }
}
Also used : WithAttributesPath(org.eclipse.titan.designer.AST.TTCN3.attributes.WithAttributesPath) Group(org.eclipse.titan.designer.AST.TTCN3.definitions.Group) Def_Type(org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Type) Attribute_Modifier_type(org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute.Attribute_Modifier_type) ArrayList(java.util.ArrayList) SingleWithAttribute(org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute) MultipleWithAttributes(org.eclipse.titan.designer.AST.TTCN3.attributes.MultipleWithAttributes) Qualifier(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier) Qualifiers(org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifiers) TTCN3Module(org.eclipse.titan.designer.AST.TTCN3.definitions.TTCN3Module)

Aggregations

ArrayList (java.util.ArrayList)5 Qualifier (org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifier)4 SingleWithAttribute (org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute)4 MultipleWithAttributes (org.eclipse.titan.designer.AST.TTCN3.attributes.MultipleWithAttributes)3 Qualifiers (org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifiers)3 IType (org.eclipse.titan.designer.AST.IType)2 WithAttributesPath (org.eclipse.titan.designer.AST.TTCN3.attributes.WithAttributesPath)2 Def_Type (org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Type)2 Group (org.eclipse.titan.designer.AST.TTCN3.definitions.Group)2 TTCN3Module (org.eclipse.titan.designer.AST.TTCN3.definitions.TTCN3Module)2 HashMap (java.util.HashMap)1 List (java.util.List)1 ASN1_Sequence_Type (org.eclipse.titan.designer.AST.ASN1.types.ASN1_Sequence_Type)1 ASN1_Set_Type (org.eclipse.titan.designer.AST.ASN1.types.ASN1_Set_Type)1 FieldSubReference (org.eclipse.titan.designer.AST.FieldSubReference)1 ISubReference (org.eclipse.titan.designer.AST.ISubReference)1 Reference (org.eclipse.titan.designer.AST.Reference)1 AttributeSpecification (org.eclipse.titan.designer.AST.TTCN3.attributes.AttributeSpecification)1 ErroneousAttributeSpecification (org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributeSpecification)1 Indicator_Type (org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributeSpecification.Indicator_Type)1