diff --git a/src/it/java/com/eprosima/integration/Test.java b/src/it/java/com/eprosima/integration/Test.java index 02ccf588..144098dd 100644 --- a/src/it/java/com/eprosima/integration/Test.java +++ b/src/it/java/com/eprosima/integration/Test.java @@ -54,6 +54,11 @@ public boolean generate( String idlPath = " " + inputPath + "/" + idl + ".idl"; + if (idl.equals("external") || idl.equals("declarations")) + { + flags = flags + " -no-typeobjectsupport"; + } + String command = program + flags + output + idlPath; return Command.execute(command, null, errorOutputOnly, true); @@ -70,6 +75,11 @@ public boolean generate( String idlPath = " " + inputPath + "/" + idl + ".idl"; + if (idl.equals("external") || idl.equals("declarations")) + { + flags = flags + " -no-typeobjectsupport"; + } + String command = program + flags + output + idlPath; return Command.execute(command, null, errorOutputOnly, true); } diff --git a/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 b/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 index 3546b131..bd13747a 100644 --- a/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 +++ b/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 @@ -1156,8 +1156,10 @@ annotation_def returns [Pair returnPair = @init { TemplateGroup annotationTemplates = null; + String old_scope = ctx.getScope(); + String name = null; } - : annotation_header LEFT_BRACE annotation_body[$annotation_header.annotation] RIGHT_BRACE + : annotation_header { if($annotation_header.annotation != null) { @@ -1172,9 +1174,24 @@ annotation_def returns [Pair returnPair = } } - $returnPair = new Pair($annotation_header.annotation, annotationTemplates); + name = $annotation_header.annotation.getName(); + + // Update to a new namespace. + if(old_scope.isEmpty()) + ctx.setScope(name); + else + ctx.setScope(old_scope + "::" + name); } } + LEFT_BRACE + annotation_body[$annotation_header.annotation] + RIGHT_BRACE + { + // Set the old namespace. + ctx.setScope(old_scope); + // Create the returned data. + $returnPair = new Pair($annotation_header.annotation, annotationTemplates); + } ; annotation_header returns [AnnotationDeclaration annotation = null] @@ -1217,7 +1234,7 @@ annotation_inheritance_spec [AnnotationDeclaration annotation] } else { - System.out.println("WARNING (File " + ctx.getFilename() + ", Line " + (_input.LT(1) != null ? _input.LT(1).getLine() - ctx.getCurrentIncludeLine() : "1") + "): Annotation " + $scoped_name.pair.first() + " not supported. Ignoring..."); + throw new ParseException($scoped_name.pair.second(), "was not defined previously"); } } } @@ -2213,7 +2230,6 @@ array_declarator returns [Pair, ContainerTypeCode>, Tem { arrayTemplates.setAttribute("array", typecode); arrayTemplates.setAttribute("ctx", ctx); - arrayTemplates.setAttribute("array_type",tk.getText()); } Pair p = new Pair(tk.getText(), tk); Pair, ContainerTypeCode> pp = new Pair, ContainerTypeCode>(p, typecode); @@ -2786,7 +2802,7 @@ annotation_appl returns [Annotation annotation = null] anndecl = ctx.getAnnotationDeclaration(name); if(anndecl == null) { - System.out.println("WARNING (File " + ctx.getFilename() + ", Line " + (_input.LT(1) != null ? _input.LT(1).getLine() - ctx.getCurrentIncludeLine() : "1") + "): Annotation " + name + " not supported. Ignoring..."); + throw new ParseException($scoped_name.pair.second(), "was not defined previously"); } else { diff --git a/src/main/java/com/eprosima/idl/context/Context.java b/src/main/java/com/eprosima/idl/context/Context.java index 72efe635..a443126c 100644 --- a/src/main/java/com/eprosima/idl/context/Context.java +++ b/src/main/java/com/eprosima/idl/context/Context.java @@ -33,6 +33,7 @@ import com.eprosima.idl.parser.typecode.BitfieldSpec; import com.eprosima.idl.parser.typecode.BitsetTypeCode; import com.eprosima.idl.parser.typecode.BitmaskTypeCode; +import com.eprosima.idl.parser.typecode.Bitmask; import com.eprosima.idl.parser.typecode.EnumMember; import com.eprosima.idl.parser.typecode.EnumTypeCode; import com.eprosima.idl.parser.typecode.Kind; @@ -201,9 +202,9 @@ public Context( TypeCode.ctypesgr = new STGroupFile("com/eprosima/idl/templates/CTypes.stg", '$', '$'); TypeCode.javatypesgr = new STGroupFile("com/eprosima/idl/templates/JavaTypes.stg", '$', '$'); - // Add here builtin annotations? (IDL 4.2 - 8.3.1 section) + // Builtin annotations (IDL 4.2 - 8.3 section & XTypes 1.3 - 7.3.1.2.1 section) AnnotationDeclaration idann = createAnnotationDeclaration(Annotation.id_str, null); - idann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_LONG), "-1")); + idann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_ULONG), Annotation.null_default_value)); AnnotationDeclaration autoidann = createAnnotationDeclaration(Annotation.autoid_str, null); EnumTypeCode autoidannenum = new EnumTypeCode(autoidann.getScopedname(), Annotation.autoid_enum_str); @@ -212,10 +213,10 @@ public Context( autoidann.addMember(new AnnotationMember(Annotation.value_str, autoidannenum, Annotation.autoid_hash_str)); AnnotationDeclaration optionalann = createAnnotationDeclaration(Annotation.optional_str, null); - optionalann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + optionalann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); - AnnotationDeclaration positionann = createAnnotationDeclaration("position", null); - positionann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_USHORT), "-1")); + AnnotationDeclaration positionann = createAnnotationDeclaration(Annotation.position_str, null); + positionann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_USHORT), Annotation.null_default_value)); AnnotationDeclaration valueann = createAnnotationDeclaration(Annotation.value_str, null); valueann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); @@ -232,71 +233,101 @@ public Context( createAnnotationDeclaration(Annotation.appendable_str, null); createAnnotationDeclaration(Annotation.mutable_str, null); - // Create default @Key annotation. + // Create default @key annotation (@Key annotation also supported and registered in parseIDL) AnnotationDeclaration keyann = createAnnotationDeclaration(Annotation.key_str, null); - keyann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + keyann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); - AnnotationDeclaration mustundann = createAnnotationDeclaration("must_understand", null); - mustundann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + AnnotationDeclaration mustundann = createAnnotationDeclaration(Annotation.must_understand_str, null); + mustundann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); - createAnnotationDeclaration("default_literal", null); + createAnnotationDeclaration(Annotation.default_literal_str, null); - AnnotationDeclaration rangeann = createAnnotationDeclaration("range", null); - rangeann.addMember(new AnnotationMember("min", new AnyTypeCode(), null)); - //String.valueOf(Integer.MIN_VALUE))); - rangeann.addMember(new AnnotationMember("max", new AnyTypeCode(), null)); - //String.valueOf(Integer.MAX_VALUE))); - - AnnotationDeclaration unitsann = createAnnotationDeclaration("units", null); - unitsann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_STRING), "")); - - AnnotationDeclaration defaultann = createAnnotationDeclaration("default", null); + AnnotationDeclaration defaultann = createAnnotationDeclaration(Annotation.default_str, null); defaultann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); - AnnotationDeclaration minann = createAnnotationDeclaration("min", null); + AnnotationDeclaration rangeann = createAnnotationDeclaration(Annotation.range_str, null); + rangeann.addMember(new AnnotationMember(Annotation.min_str, new AnyTypeCode(), null)); + rangeann.addMember(new AnnotationMember(Annotation.max_str, new AnyTypeCode(), null)); + + AnnotationDeclaration minann = createAnnotationDeclaration(Annotation.min_str, null); minann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); - AnnotationDeclaration maxann = createAnnotationDeclaration("max", null); + AnnotationDeclaration maxann = createAnnotationDeclaration(Annotation.max_str, null); maxann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); - AnnotationDeclaration bit_boundann = createAnnotationDeclaration("bit_bound", null); - bit_boundann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_USHORT), "-1")); + AnnotationDeclaration unitsann = createAnnotationDeclaration(Annotation.unit_str, null); + unitsann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_STRING), Annotation.empty_str)); + + AnnotationDeclaration bit_boundann = createAnnotationDeclaration(Annotation.bit_bound_str, null); + bit_boundann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_USHORT), Annotation.null_default_value)); AnnotationDeclaration externalann = createAnnotationDeclaration(Annotation.external_str, null); - externalann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); - - AnnotationDeclaration nestedann = createAnnotationDeclaration("nested", null); - nestedann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); - - AnnotationDeclaration verbatimann = createAnnotationDeclaration("verbatim", null); - EnumTypeCode verbatimannenum = new EnumTypeCode(verbatimann.getScopedname(), "verbatimannenum"); - verbatimannenum.addMember(new EnumMember("BEGIN_FILE")); - verbatimannenum.addMember(new EnumMember("BEFORE_DECLARATION")); - verbatimannenum.addMember(new EnumMember("BEGIN_DECLARATION")); - verbatimannenum.addMember(new EnumMember("END_DECLARATION")); - verbatimannenum.addMember(new EnumMember("AFTER_DECLARATION")); - verbatimannenum.addMember(new EnumMember("END_FILE")); - verbatimann.addMember(new AnnotationMember("language", new PrimitiveTypeCode(Kind.KIND_STRING), "*")); + externalann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); + + AnnotationDeclaration nestedann = createAnnotationDeclaration(Annotation.nested_str, null); + nestedann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); + + AnnotationDeclaration verbatimann = createAnnotationDeclaration(Annotation.verbatim_str, null); + EnumTypeCode verbatimannenum = new EnumTypeCode(verbatimann.getScopedname(), Annotation.placement_enum_str); + verbatimannenum.addMember(new EnumMember(Annotation.begin_file_str)); + verbatimannenum.addMember(new EnumMember(Annotation.before_declaration_str)); + verbatimannenum.addMember(new EnumMember(Annotation.begin_declaration_str)); + verbatimannenum.addMember(new EnumMember(Annotation.end_declaration_str)); + verbatimannenum.addMember(new EnumMember(Annotation.after_declaration_str)); + verbatimannenum.addMember(new EnumMember(Annotation.end_file_str)); + verbatimann.addMember(new AnnotationMember(Annotation.language_str, new PrimitiveTypeCode(Kind.KIND_STRING), Annotation.any_str)); // c, c++, java, idl, * (any), or custom value - verbatimann.addMember(new AnnotationMember("placement", verbatimannenum, "BEFORE_DECLARATION")); - verbatimann.addMember(new AnnotationMember("text", new PrimitiveTypeCode(Kind.KIND_STRING), "")); + verbatimann.addMember(new AnnotationMember(Annotation.placement_str, verbatimannenum, Annotation.before_declaration_str)); + verbatimann.addMember(new AnnotationMember(Annotation.text_str, new PrimitiveTypeCode(Kind.KIND_STRING), Annotation.empty_str)); - AnnotationDeclaration serviceann = createAnnotationDeclaration("service", null); - serviceann.addMember(new AnnotationMember("platform", new PrimitiveTypeCode(Kind.KIND_STRING), "*")); + AnnotationDeclaration serviceann = createAnnotationDeclaration(Annotation.service_str, null); + serviceann.addMember(new AnnotationMember(Annotation.platform_str, new PrimitiveTypeCode(Kind.KIND_STRING), Annotation.any_str)); // CORBA, DDS, * (any), or custom value - AnnotationDeclaration onewayann = createAnnotationDeclaration("oneway", null); - onewayann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + AnnotationDeclaration onewayann = createAnnotationDeclaration(Annotation.oneway_str, null); + onewayann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); - AnnotationDeclaration amiann = createAnnotationDeclaration("ami", null); - amiann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + AnnotationDeclaration amiann = createAnnotationDeclaration(Annotation.ami_str, null); + amiann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); AnnotationDeclaration hashid_annotation = createAnnotationDeclaration(Annotation.hashid_str, null); - hashid_annotation.addMember(new AnnotationMember(Annotation.value_str, new StringTypeCode(Kind.KIND_STRING, null, null), "")); + hashid_annotation.addMember(new AnnotationMember(Annotation.value_str, new StringTypeCode(Kind.KIND_STRING, null, null), Annotation.empty_str)); + + AnnotationDeclaration default_nested_annotation = createAnnotationDeclaration(Annotation.default_nested_str, null); + default_nested_annotation.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); + + AnnotationDeclaration ignore_literal_names_annotation = createAnnotationDeclaration(Annotation.ignore_literal_names_str, null); + ignore_literal_names_annotation.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); + + EnumTypeCode try_construct_fail_action_enum = new EnumTypeCode(null, Annotation.try_construct_enum_str); + try_construct_fail_action_enum.addMember(new EnumMember(Annotation.try_construct_discard_str)); + try_construct_fail_action_enum.addMember(new EnumMember(Annotation.try_construct_use_default_str)); + try_construct_fail_action_enum.addMember(new EnumMember(Annotation.try_construct_trim_str)); + + AnnotationDeclaration try_construct_annotation = createAnnotationDeclaration(Annotation.try_construct_str, null); + try_construct_annotation.addMember(new AnnotationMember(Annotation.value_str, try_construct_fail_action_enum, Annotation.try_construct_use_default_str)); // Create default @non_serialized annotation. - AnnotationDeclaration non_serializedann = createAnnotationDeclaration("non_serialized", null); - non_serializedann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + AnnotationDeclaration non_serializedann = createAnnotationDeclaration(Annotation.non_serialized_str, null); + non_serializedann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), Annotation.true_str)); + + BitmaskTypeCode data_representation_mask_bitmask = new BitmaskTypeCode(null, Annotation.data_representation_mask_str); + Bitmask xcdr1_bitmask = new Bitmask(data_representation_mask_bitmask, Annotation.xcdr1_bitflag_str); + xcdr1_bitmask.setPosition(0); + data_representation_mask_bitmask.addBitmask(xcdr1_bitmask); + Bitmask xml_bitmask = new Bitmask(data_representation_mask_bitmask, Annotation.xml_bitflag_str); + xml_bitmask.setPosition(1); + data_representation_mask_bitmask.addBitmask(xml_bitmask); + Bitmask xcdr2_bitmask = new Bitmask(data_representation_mask_bitmask, Annotation.xcdr2_bitflag_str); + xcdr2_bitmask.setPosition(2); + data_representation_mask_bitmask.addBitmask(xcdr2_bitmask); + + AnnotationDeclaration data_representation_annotation = createAnnotationDeclaration(Annotation.data_representation_str, null); + data_representation_annotation.addMember(new AnnotationMember(Annotation.allowed_kinds_str, data_representation_mask_bitmask, Annotation.empty_str)); + + AnnotationDeclaration topic_annotation = createAnnotationDeclaration(Annotation.topic_str, null); + topic_annotation.addMember(new AnnotationMember(Annotation.name_str, new PrimitiveTypeCode(Kind.KIND_STRING), Annotation.empty_str)); + topic_annotation.addMember(new AnnotationMember(Annotation.platform_str, new PrimitiveTypeCode(Kind.KIND_STRING), Annotation.any_str)); } public String getFilename() diff --git a/src/main/java/com/eprosima/idl/parser/tree/Annotation.java b/src/main/java/com/eprosima/idl/parser/tree/Annotation.java index ac8b21aa..1de56841 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/Annotation.java +++ b/src/main/java/com/eprosima/idl/parser/tree/Annotation.java @@ -18,17 +18,28 @@ import java.util.HashMap; import java.util.Collection; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; +import com.eprosima.idl.parser.typecode.TypeCode; + public class Annotation { + public static final String null_default_value = "0"; + public static final String true_str = "true"; + public static final String capitalized_true_str = "TRUE"; + public static final String empty_str = ""; + public static final String any_str = "*"; + public static final String autoid_str = "autoid"; public static final String autoid_enum_str = "AutoidKind"; public static final String autoid_sequential_str = "SEQUENTIAL"; public static final String autoid_sequential_value_str = "0"; public static final String autoid_hash_str = "HASH"; + public static final String autoid_hash_value_str = "1"; public static final String hashid_str = "hashid"; public static final String id_str = "id"; public static final String key_str = "key"; + public static final String eprosima_key_str = "Key"; public static final String extensibility_str = "extensibility"; public static final String extensibility_enum_str = "ExtensibilityKind"; @@ -46,6 +57,51 @@ public class Annotation public static final String optional_str = "optional"; public static final String external_str = "external"; + public static final String position_str = "position"; + public static final String must_understand_str = "must_understand"; + public static final String default_literal_str = "default_literal"; + public static final String default_str = "default"; + public static final String range_str = "range"; + public static final String min_str = "min"; + public static final String max_str = "max"; + public static final String unit_str = "unit"; + public static final String bit_bound_str = "bit_bound"; + public static final String nested_str = "nested"; + public static final String default_nested_str = "default_nested"; + public static final String ignore_literal_names_str = "ignore_literal_names"; + + public static final String verbatim_str = "verbatim"; + public static final String placement_enum_str = "PlacementKind"; + public static final String begin_file_str = "BEGIN_FILE"; + public static final String before_declaration_str = "BEFORE_DECLARATION"; + public static final String begin_declaration_str = "BEGIN_DECLARATION"; + public static final String end_declaration_str = "END_DECLARATION"; + public static final String after_declaration_str = "AFTER_DECLARATION"; + public static final String end_file_str = "END_FILE"; + public static final String language_str = "language"; + public static final String placement_str = "placement"; + public static final String text_str = "text"; + + public static final String service_str = "service"; + public static final String platform_str = "platform"; + public static final String oneway_str = "oneway"; + public static final String ami_str = "ami"; + + public static final String non_serialized_str = "non_serialized"; + public static final String data_representation_mask_str = "DataRepresentationMask"; + public static final String xcdr1_bitflag_str = "XCDR1"; + public static final String xml_bitflag_str = "XML"; + public static final String xcdr2_bitflag_str = "XCDR2"; + public static final String data_representation_str = "data_representation"; + public static final String allowed_kinds_str = "allowed_kinds"; + public static final String topic_str = "topic"; + public static final String name_str = "name"; + + public static final String try_construct_str = "try_construct"; + public static final String try_construct_enum_str = "TryConstructFailAction"; + public static final String try_construct_discard_str = "DISCARD"; + public static final String try_construct_use_default_str = "USE_DEFAULT"; + public static final String try_construct_trim_str = "TRIM"; public Annotation(AnnotationDeclaration declaration) { @@ -69,10 +125,57 @@ public String getName() return null; } + /*! + * @brief Returns the full scoped name of the type, unless the developer uses + * `TemplateSTGroup.enable_using_explicitly_modules()`, by removing from the full scoped name the current + * `Context` scope. + */ + public String getScopedname() throws RuntimeGenerationException + { + String scoped_name = getFullScopedname(); + + if (!com.eprosima.idl.parser.typecode.TypeCode.ctx.is_enabled_custom_property_in_current_group(com.eprosima.idl.parser.typecode.TypeCode.ctx.using_explicitly_modules_custom_property)) + { + return scoped_name; + } + + String current_scope = com.eprosima.idl.parser.typecode.TypeCode.ctx.getScope(); + + if(current_scope.isEmpty() || !scoped_name.startsWith(current_scope + "::")) + { + return scoped_name; + } + + return scoped_name.replace(current_scope + "::", ""); + } + + /*! + * @brief Return the scoped name of the type. + */ + public String getFullScopedname() throws RuntimeGenerationException + { + if(m_declaration == null) + { + throw new RuntimeGenerationException("Annotation declaration not initialized"); + } + return m_declaration.getScopedname(); + } + + public String getROS2Scopedname() throws RuntimeGenerationException + { + if(m_declaration == null) + { + throw new RuntimeGenerationException("Annotation declaration not initialized"); + } + return m_declaration.getROS2Scopedname(); + } + public boolean addValue(String value) { if(m_members.size() != 1) + { return false; + } ((AnnotationMember)m_members.values().toArray()[0]).setValue(value); @@ -86,16 +189,25 @@ public boolean addValue(String attribute, String value) if(member != null) { member.setValue(value); + // Check that in case of an Enum the set value is in the enumeration. + // ParseException is thrown otherwise. + member.getEnumStringValue(); } else + { return false; + } return true; } - public String getValue() + public String getValue() throws RuntimeGenerationException { - if(m_members.size() != 1) return null; + if(m_members.size() != 1) + { + throw new RuntimeGenerationException("Error in annotation " + getName() + + ": accessing value of a multiple parameter exception"); + } return ((AnnotationMember)m_members.values().toArray()[0]).getValue(); } @@ -115,6 +227,81 @@ public Collection getValueList() return m_members.values(); } + public boolean isIsVerbatim() + { + return getName().equals(Annotation.verbatim_str); + } + + public boolean isIsUnit() + { + return getName().equals(Annotation.unit_str); + } + + public boolean isIsMax() + { + return getName().equals(Annotation.max_str); + } + + public boolean isIsMin() + { + return getName().equals(Annotation.min_str); + } + + public boolean isIsRange() + { + return getName().equals(Annotation.range_str); + } + + public boolean isIsHashId() + { + return getName().equals(Annotation.hashid_str); + } + + public boolean isIsBuiltin() + { + if (getName().equals(Annotation.id_str) || + getName().equals(Annotation.autoid_str) || + getName().equals(Annotation.optional_str) || + getName().equals(Annotation.position_str) || + getName().equals(Annotation.value_str) || + getName().equals(Annotation.extensibility_str) || + getName().equals(Annotation.final_str) || + getName().equals(Annotation.appendable_str) || + getName().equals(Annotation.mutable_str) || + getName().equals(Annotation.key_str) || + getName().equals(Annotation.eprosima_key_str) || + getName().equals(Annotation.must_understand_str) || + getName().equals(Annotation.default_literal_str) || + getName().equals(Annotation.default_str) || + getName().equals(Annotation.range_str) || + getName().equals(Annotation.min_str) || + getName().equals(Annotation.max_str) || + getName().equals(Annotation.unit_str) || + getName().equals(Annotation.bit_bound_str) || + getName().equals(Annotation.external_str) || + getName().equals(Annotation.nested_str) || + getName().equals(Annotation.verbatim_str) || + getName().equals(Annotation.service_str) || + getName().equals(Annotation.oneway_str) || + getName().equals(Annotation.ami_str) || + getName().equals(Annotation.hashid_str) || + getName().equals(Annotation.default_nested_str) || + getName().equals(Annotation.ignore_literal_names_str) || + getName().equals(Annotation.try_construct_str) || + getName().equals(Annotation.non_serialized_str) || + getName().equals(Annotation.data_representation_str) || + getName().equals(Annotation.topic_str)) + { + return true; + } + return false; + } + + public int getValuesSize() + { + return m_members.size(); + } + private HashMap m_members = null; private AnnotationDeclaration m_declaration = null; } diff --git a/src/main/java/com/eprosima/idl/parser/tree/AnnotationDeclaration.java b/src/main/java/com/eprosima/idl/parser/tree/AnnotationDeclaration.java index 74aab890..60ce4d4f 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/AnnotationDeclaration.java +++ b/src/main/java/com/eprosima/idl/parser/tree/AnnotationDeclaration.java @@ -42,6 +42,11 @@ public List getMembers() return new ArrayList(m_members.values()); } + public int getMembersSize() + { + return m_members.values().size(); + } + public void addMembers(AnnotationDeclaration annotation) { m_members.putAll(annotation.m_members); @@ -49,6 +54,9 @@ public void addMembers(AnnotationDeclaration annotation) public boolean addMember(AnnotationMember member) { + // Check that in case of an Enum the given value is in the enumeration. + // ParseException is thrown otherwise. + member.getEnumStringValue(); if(!m_members.containsKey(member.getName())) { m_members.put(member.getName(), member); diff --git a/src/main/java/com/eprosima/idl/parser/tree/AnnotationMember.java b/src/main/java/com/eprosima/idl/parser/tree/AnnotationMember.java index 5f2d9365..0984b852 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/AnnotationMember.java +++ b/src/main/java/com/eprosima/idl/parser/tree/AnnotationMember.java @@ -14,6 +14,7 @@ package com.eprosima.idl.parser.tree; +import com.eprosima.idl.parser.exception.ParseException; import com.eprosima.idl.parser.typecode.Member; import com.eprosima.idl.parser.typecode.EnumMember; import com.eprosima.idl.parser.typecode.EnumTypeCode; @@ -51,20 +52,26 @@ public TypeCode getTypecode() public String getValue() { - if (m_typecode.isIsType_c()) // Enum + if (m_typecode.isIsEnumType()) { EnumTypeCode enumTC = (EnumTypeCode)m_typecode; int idx = 0; + int default_idx = 0; for (Member m : enumTC.getMembers()) { if (m.getName().equals(m_value)) { return Integer.toString(idx); } + else if (m.isAnnotationDefaultLiteral()) + { + default_idx = idx; + } idx++; } + return Integer.toString(default_idx); } - if (m_typecode.isIsType_d()) // String + else if (m_typecode.isIsStringType() || m_typecode.isIsWStringType()) { if (m_value != null) { @@ -73,8 +80,13 @@ public String getValue() return m_value.substring(1, m_value.length() - 1); } } + if (m_typecode.isIsWStringType()) + { + return "L\"\""; + } + return ""; } - if (m_typecode.isPrimitiveType()) + else if (m_typecode.isPrimitiveType()) { if (m_value != null) { @@ -86,6 +98,31 @@ public String getValue() return m_value; } } + return m_typecode.getInitialValue(); + } + return m_value; + } + + public String getEnumStringValue() + { + if (m_value != null && m_typecode.isIsEnumType()) + { + EnumTypeCode enumTC = (EnumTypeCode)m_typecode; + for (Member m : enumTC.getMembers()) + { + String value = m_value; + if (value.startsWith("\"") && value.endsWith("\"")) + { + value = value.substring(1, value.length() - 1); + } + String[] value_with_scopes = value.split("::"); + value = value_with_scopes[value_with_scopes.length - 1]; + if (m.getName().equals(value)) + { + return value; + } + } + throw new ParseException(null, m_value + " is not a valid label for " + m_name); } return m_value; } @@ -95,6 +132,31 @@ public void setValue(String value) m_value = value; } + public boolean isIsVerbatimPlacement() + { + return getName().equals(Annotation.placement_str); + } + + public boolean isIsVerbatimLanguage() + { + return getName().equals(Annotation.language_str); + } + + public boolean isIsVerbatimText() + { + return getName().equals(Annotation.text_str); + } + + public boolean isIsMax() + { + return getName().equals(Annotation.max_str); + } + + public boolean isIsMin() + { + return getName().equals(Annotation.min_str); + } + private String m_name = null; private TypeCode m_typecode = null; diff --git a/src/main/java/com/eprosima/idl/parser/tree/TreeNode.java b/src/main/java/com/eprosima/idl/parser/tree/TreeNode.java index 981efe24..3fead6fb 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/TreeNode.java +++ b/src/main/java/com/eprosima/idl/parser/tree/TreeNode.java @@ -51,7 +51,9 @@ public String getName() public String getScopedname() { if(m_scope == null || m_scope.isEmpty()) + { return m_name; + } return m_scope + "::" + m_name; } @@ -59,7 +61,9 @@ public String getScopedname() public String getROS2Scopedname() { if(m_scope == null || m_scope.isEmpty()) + { return m_name; + } return m_scope + "::dds_::" + m_name + "_"; } @@ -67,7 +71,9 @@ public String getROS2Scopedname() public String getCScopedname() { if(m_scope.isEmpty()) + { return m_name; + } return m_scope.replace("::", "_") + "_" + m_name; } @@ -75,7 +81,9 @@ public String getCScopedname() public String getJavaScopedname() { if(m_scope.isEmpty()) + { return m_name; + } return m_scope.replace("::", ".") + "." + m_name; } @@ -94,9 +102,13 @@ public String getFormatedScopedname() String ret = null; if(m_scope == null || m_scope.isEmpty()) + { ret = m_name; + } else + { ret = m_scope + "::" + m_name; + } return ret.replaceAll("::", "_"); } @@ -110,7 +122,9 @@ public boolean getHasScope() public void addAnnotation(Context ctx, Annotation annotation) { if(annotation != null) + { m_annotations.put(annotation.getName(), annotation); + } } @Override diff --git a/src/main/java/com/eprosima/idl/parser/typecode/AliasTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/AliasTypeCode.java index 313e909f..d6a7afd0 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/AliasTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/AliasTypeCode.java @@ -14,6 +14,7 @@ package com.eprosima.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.util.Pair; import java.util.List; import org.stringtemplate.v4.ST; @@ -327,14 +328,31 @@ public String getSize() return super.getContentTypeCode().getSize(); } - public List getDimensions() + public String getEvaluatedMaxsize() throws RuntimeGenerationException + { + return super.getContentTypeCode().getEvaluatedMaxsize(); + } + + public List getDimensions() throws RuntimeGenerationException { if (super.getContentTypeCode() instanceof ArrayTypeCode) { return ((ArrayTypeCode) super.getContentTypeCode()).getDimensions(); } - return null; + throw new RuntimeGenerationException("Error in alias " + m_name + + ": trying accessing dimensions for a non-array type"); + } + + public List getEvaluatedDimensions() throws RuntimeGenerationException + { + if (super.getContentTypeCode() instanceof ArrayTypeCode) + { + return ((ArrayTypeCode) super.getContentTypeCode()).getEvaluatedDimensions(); + } + + throw new RuntimeGenerationException("Error in alias " + m_name + + ": trying accessing dimensions for a non-array type"); } public int getFullBitSize() diff --git a/src/main/java/com/eprosima/idl/parser/typecode/ArrayTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/ArrayTypeCode.java index ad307726..987a1095 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/ArrayTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/ArrayTypeCode.java @@ -36,7 +36,15 @@ public boolean isIsType_f() @Override public String getTypeIdentifier() { - return "TI_PLAIN_ARRAY_SMALL"; + String type_id = "TI_PLAIN_ARRAY_SMALL"; + for (int count = 0; count < evaluated_dimensions_.size(); ++count) + { + if (Integer.parseInt(evaluated_dimensions_.get(count)) >= 256) + { + return "TI_PLAIN_ARRAY_LARGE"; + } + } + return type_id; } @Override @@ -185,6 +193,11 @@ public List getEvaluatedDimensions() return evaluated_dimensions_; } + public int getEvaluatedDimensionsSize() + { + return evaluated_dimensions_.size(); + } + public String getSize() { String ret = ""; diff --git a/src/main/java/com/eprosima/idl/parser/typecode/BitfieldSpec.java b/src/main/java/com/eprosima/idl/parser/typecode/BitfieldSpec.java index 262654e5..9355b067 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/BitfieldSpec.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/BitfieldSpec.java @@ -26,7 +26,7 @@ public static int generateKind( } else if (size <= 8) { - return Kind.KIND_CHAR; + return Kind.KIND_OCTET; } else if (size <= 16) { diff --git a/src/main/java/com/eprosima/idl/parser/typecode/BitmaskTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/BitmaskTypeCode.java index 224c4414..aea27586 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/BitmaskTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/BitmaskTypeCode.java @@ -20,6 +20,7 @@ import java.util.Set; import com.eprosima.idl.parser.exception.ParseException; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.tree.Annotation; import com.eprosima.idl.context.Context; @@ -133,8 +134,15 @@ public boolean addBitmask( { if (bitmask.getAnnotations().get("position") != null) { - // Position from attribute - return addBitmask(bitmask, Integer.parseInt(bitmask.getAnnotations().get("position").getValue())); + try + { + // Position from attribute + return addBitmask(bitmask, Integer.parseInt(bitmask.getAnnotations().get("position").getValue())); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @position annotation has only one parameter + } } // Position autoassigned return addBitmask(bitmask, m_current_base); @@ -232,17 +240,24 @@ public void addAnnotation( super.addAnnotation(ctx, annotation); if (annotation.getName().equals("bit_bound")) { - m_bit_bound = Integer.parseInt(annotation.getValue()); - // Sanity check - Set keys = m_bitmasks.keySet(); - for (String key : keys) { - int position = m_bitmasks.get(key).getPosition(); - if (position < 0 || position >= m_bit_bound) - { - throw new ParseException(null, "Bitmask member "+ key +" out of bounds. Requested position: " - + position + " with @bit_bound value: " + m_bit_bound); + try + { + m_bit_bound = Integer.parseInt(annotation.getValue()); + // Sanity check + Set keys = m_bitmasks.keySet(); + for (String key : keys) { + int position = m_bitmasks.get(key).getPosition(); + if (position < 0 || position >= m_bit_bound) + { + throw new ParseException(null, "Bitmask member "+ key +" out of bounds. Requested position: " + + position + " with @bit_bound value: " + m_bit_bound); + } } } + catch (RuntimeGenerationException ex) + { + // Should not be called as @bit_bound annotation only has one parameter + } } } diff --git a/src/main/java/com/eprosima/idl/parser/typecode/BitsetTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/BitsetTypeCode.java index 55fcaca0..baf7f6df 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/BitsetTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/BitsetTypeCode.java @@ -104,7 +104,12 @@ public List getAllBitfields() // Alias for getBitfields(true) for stg public boolean addBitfield( Bitfield bitfield) { - if (!m_bitfields.containsKey(bitfield.getName())) + if (null == bitfield.getName()) + { + m_current_base += bitfield.getSpec().getBitSize(); + return true; + } + if (!m_bitfields.containsKey(bitfield.getName()) ) { m_bitfields.put(bitfield.getName(), bitfield); bitfield.setBasePosition(m_current_base); @@ -161,13 +166,7 @@ public TypeCode getEnclosedInheritance() public int getBitSize() { - int size = 0; - - for (Bitfield bf : m_bitfields.values()) - { - size += bf.getSpec().getBitSize(); - } - return size; + return m_current_base; } public int getFullBitSize() @@ -179,11 +178,7 @@ public int getFullBitSize() size += enclosed_super_type_.getFullBitSize(); } - for (Bitfield bf : m_bitfields.values()) - { - size += bf.getSpec().getBitSize(); - } - return size; + return m_current_base + size; } private BitsetTypeCode enclosed_super_type_ = null; diff --git a/src/main/java/com/eprosima/idl/parser/typecode/EnumTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/EnumTypeCode.java index 284be58d..cfd107b1 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/EnumTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/EnumTypeCode.java @@ -133,5 +133,11 @@ public boolean isIsPlain() { return true; } + + public int getBitBound() + { + // TODO: pending @bit_bound annotation application to enum types + return 32; + } } diff --git a/src/main/java/com/eprosima/idl/parser/typecode/MapTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/MapTypeCode.java index 6f87e910..301a0a71 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MapTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MapTypeCode.java @@ -37,6 +37,10 @@ public boolean isIsType_19() @Override public String getTypeIdentifier() { + if (isIsBounded() && Integer.parseInt(evaluated_maxsize_) >= 256) + { + return "TI_PLAIN_MAP_LARGE"; + } return "TI_PLAIN_MAP_SMALL"; } @@ -92,6 +96,7 @@ public String getIdlTypename() return st.render(); } + @Override public String getMaxsize() { if (m_maxsize == null) @@ -102,6 +107,7 @@ public String getMaxsize() return m_maxsize; } + @Override public String getEvaluatedMaxsize() { if (evaluated_maxsize_ == null) diff --git a/src/main/java/com/eprosima/idl/parser/typecode/MemberAppliedAnnotations.java b/src/main/java/com/eprosima/idl/parser/typecode/MemberAppliedAnnotations.java index e1cc1dd3..2ac2cdc8 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberAppliedAnnotations.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberAppliedAnnotations.java @@ -19,11 +19,34 @@ import java.util.Map; import com.eprosima.idl.context.Context; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.tree.Annotation; import com.eprosima.idl.parser.tree.Notebook; public class MemberAppliedAnnotations implements Notebook { + public enum TryConstructFailAction + { + INVALID(0), + DISCARD(1), + USE_DEFAULT(2), + TRIM(3); + + private int value_ = 0; + + private TryConstructFailAction(int value) + { + value_ = value; + } + + public int get_value() + { + return value_; + } + }; + + public static TryConstructFailAction default_try_construct = TryConstructFailAction.DISCARD; + @Override public void addAnnotation(Context ctx, Annotation annotation) { @@ -49,7 +72,14 @@ public boolean isAnnotationOptional() Annotation ann = m_annotations.get(Annotation.optional_str); if (ann != null) { - return ann.getValue().toUpperCase().equals("TRUE"); + try + { + return ann.getValue().toUpperCase().equals(Annotation.capitalized_true_str); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @optional annotation only has one parameter + } } return false; } @@ -59,104 +89,226 @@ public boolean isAnnotationExternal() Annotation ann = m_annotations.get(Annotation.external_str); if (ann != null) { - return ann.getValue().toUpperCase().equals("TRUE"); + try + { + return ann.getValue().toUpperCase().equals(Annotation.capitalized_true_str); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @external annotation has only one parameter + } } return false; } public boolean isAnnotationMustUnderstand() { - Annotation ann = m_annotations.get("must_understand"); + Annotation ann = m_annotations.get(Annotation.must_understand_str); if (ann != null) { - return ann.getValue().toUpperCase().equals("TRUE"); + try + { + return ann.getValue().toUpperCase().equals(Annotation.capitalized_true_str); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @must_understand annotation has only one parameter + } } return false; } public boolean isAnnotationNonSerialized() { - Annotation ann = m_annotations.get("non_serialized"); + Annotation ann = m_annotations.get(Annotation.non_serialized_str); if (ann != null) { - return ann.getValue().toUpperCase().equals("TRUE"); + try + { + return ann.getValue().toUpperCase().equals(Annotation.capitalized_true_str); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @non_serialized annotation has only one parameter + } } return false; } public boolean isAnnotationKey() { - Annotation ann = m_annotations.get("key"); + Annotation ann = m_annotations.get(Annotation.key_str); if (ann == null) { - ann = m_annotations.get("Key"); // Try old way + ann = m_annotations.get(Annotation.eprosima_key_str); // Try old way } if (ann != null) { - return ann.getValue().toUpperCase().equals("TRUE"); + try + { + return ann.getValue().toUpperCase().equals(Annotation.capitalized_true_str); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @key annotation has only one parameter + } } return false; } - public Short getAnnotationBitBound() + public boolean isAnnotationBitBound() { - Annotation ann = m_annotations.get("bit_bound"); - if (ann != null) + return m_annotations.get(Annotation.bit_bound_str) != null; + } + + public Short getAnnotationBitBoundValue() throws RuntimeGenerationException + { + try { - String value = ann.getValue(); - if (value.equals("-1")) + if (isAnnotationBitBound()) { - return null; + return Short.parseShort(m_annotations.get(Annotation.bit_bound_str).getValue()); } - return Short.parseShort(value); } - return null; + catch (RuntimeGenerationException ex) + { + // Should never be called because isAnnotationBitBound() was previously called. + } + return 0; } public boolean isAnnotationDefaultLiteral() { - return m_annotations.get("default_literal") != null; + return m_annotations.get(Annotation.default_literal_str) != null; } - public String getAnnotationValue() + public boolean isAnnotationValue() { - Annotation ann = m_annotations.get("value"); - if (ann != null) + return m_annotations.get(Annotation.value_str) != null; + } + + public String getAnnotationValueValue() + { + try { - return ann.getValue(); + if (isAnnotationValue()) + { + return m_annotations.get(Annotation.value_str).getValue(); + } + } + catch (RuntimeGenerationException ex) + { + // Should never be called because isAnnotationValue() was previously called. } - return null; + return ""; } - public Short getAnnotationPosition() + public boolean isAnnotationPosition() { - Annotation ann = m_annotations.get("position"); - if (ann != null) + return m_annotations.get(Annotation.position_str) != null; + } + + public Short getAnnotationPositionValue() + { + try { - String value = ann.getValue(); - if (value.equals("-1")) + if (isAnnotationPosition()) { - return null; + return Short.parseShort(m_annotations.get(Annotation.position_str).getValue()); } - return Short.parseShort(value); } - return null; + catch (RuntimeGenerationException ex) + { + // Should never be called because isAnnotationPosition() was previously called. + } + return 0; } public boolean isAnnotationDefault() { - return m_annotations.get("default") != null; + return m_annotations.get(Annotation.default_str) != null; } - public String getAnnotationDefaultValue() + public String getAnnotationDefaultValue() throws RuntimeGenerationException { - Annotation ann = m_annotations.get("default"); + Annotation ann = m_annotations.get(Annotation.default_str); if (ann != null) { return ann.getValue(); } - return ""; + throw new RuntimeGenerationException("Error getting @default annotation value: annotation not found"); + } + + public boolean isAnnotationTryConstruct() + { + return m_annotations.containsKey(Annotation.try_construct_str); + } + + void calculate_try_construct() throws RuntimeGenerationException + { + if (TryConstructFailAction.INVALID == try_construct_) + { + if (isAnnotationTryConstruct()) + { + if (m_annotations.get(Annotation.try_construct_str).getValue().equals(Annotation.try_construct_discard_str)) + { + try_construct_ = TryConstructFailAction.DISCARD; + } + else if (m_annotations.get(Annotation.try_construct_str).getValue().equals(Annotation.try_construct_use_default_str)) + { + try_construct_ = TryConstructFailAction.USE_DEFAULT; + } + else if (m_annotations.get(Annotation.try_construct_str).getValue().equals(Annotation.try_construct_trim_str)) + { + try_construct_ = TryConstructFailAction.TRIM; + } + else + { + throw new RuntimeGenerationException("try_construct annotation does not have a recognized value"); + } + } + else + { + try_construct_ = default_try_construct; + } + } + } + + public TryConstructFailAction get_try_construct() throws RuntimeGenerationException + { + calculate_try_construct(); + return try_construct_; + } + + public boolean isAnnotationDiscard() throws RuntimeGenerationException + { + calculate_try_construct(); + return TryConstructFailAction.DISCARD == try_construct_; + } + + public boolean isAnnotationUseDefault() throws RuntimeGenerationException + { + calculate_try_construct(); + return TryConstructFailAction.USE_DEFAULT == try_construct_; + } + + public boolean isAnnotationTrim() throws RuntimeGenerationException + { + calculate_try_construct(); + return TryConstructFailAction.TRIM == try_construct_; + } + + public boolean isAnnotationId() + { + return m_annotations.get(Annotation.id_str) != null; + } + + public boolean isAnnotationHashid() + { + return m_annotations.get(Annotation.hashid_str) != null; } private HashMap m_annotations = new HashMap(); + + private TryConstructFailAction try_construct_ = TryConstructFailAction.INVALID; } diff --git a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java index ace83767..37b216c6 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -131,6 +131,11 @@ public List getMembers() return new ArrayList(m_members.values()); } + public int getMembersSize() + { + return m_members.size(); + } + public boolean addMember( Member member) throws ParseException { @@ -161,7 +166,7 @@ public boolean addMember( throw new ParseException(null, "Error in member " + member.getName() + ": @" + Annotation.key_str + " annotations only supported for structure's members (Union discriminator still pending implementation)."); } - if (null != member.getAnnotationBitBound() && ( + if (member.isAnnotationBitBound() && ( Kind.KIND_ENUM != getKind() && Kind.KIND_BITMASK != getKind())) { throw new ParseException(null, "Error in member " + member.getName() + @@ -172,12 +177,12 @@ public boolean addMember( throw new ParseException(null, "Error in member " + member.getName() + ": @default_literal annotations only supported for enumeration's members."); } - if (null != member.getAnnotationValue() && Kind.KIND_ENUM != getKind()) + if (member.isAnnotationValue() && Kind.KIND_ENUM != getKind()) { throw new ParseException(null, "Error in member " + member.getName() + ": @value annotations only supported for enumeration's members."); } - if (null != member.getAnnotationPosition() && Kind.KIND_BITMASK != getKind()) + if (member.isAnnotationPosition() && Kind.KIND_BITMASK != getKind()) { throw new ParseException(null, "Error in member " + member.getName() + ": @position annotations only supported for bitmask's members."); @@ -204,7 +209,7 @@ public boolean addMember( { throw new ParseException(null, "Error in member " + member.getName() + ": @" + Annotation.hashid_str + - "annotations only supported for structure's members or union's members."); + "annotations only supported for structure's members or union's members."); } if (member.isAnnotationId() && member.isAnnotationHashid()) { @@ -273,7 +278,7 @@ else if (!isAnnotationAutoid() || getAnnotationAutoidValue().equals(Annotation.a } catch (RuntimeGenerationException ex) { - // Should be never called because was previously called isAnnotationId() or similar. + // Should never be called because isAnnotationId() or similar was previously called. } } @@ -397,6 +402,18 @@ public String getAnnotationAutoidValue() throws RuntimeGenerationException return ann.getValue(); } + public boolean isNonForwardedContent() + { + for (Member member : m_members.values()) + { + if (member.getTypecode().isForwarded()) + { + return false; + } + } + return true; + } + private String m_name = null; private String m_scope = null; diff --git a/src/main/java/com/eprosima/idl/parser/typecode/PrimitiveTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/PrimitiveTypeCode.java index c1d1c92d..4e65c099 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/PrimitiveTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/PrimitiveTypeCode.java @@ -182,10 +182,94 @@ public boolean isIsType_13() return getKind() == Kind.KIND_LONGDOUBLE; } + @Override + public boolean isIsCharType() + { + return getKind() == Kind.KIND_CHAR; + } + @Override public boolean isIsWCharType() { return getKind() == Kind.KIND_WCHAR; } + @Override + public boolean isIsBooleanType() + { + return getKind() == Kind.KIND_BOOLEAN; + } + + @Override + public boolean isIsByteType() + { + return getKind() == Kind.KIND_OCTET; + } + + @Override + public boolean isIsInt8Type() + { + return getKind() == Kind.KIND_INT8; + } + + @Override + public boolean isIsUint8Type() + { + return getKind() == Kind.KIND_UINT8; + } + + @Override + public boolean isIsInt16Type() + { + return getKind() == Kind.KIND_SHORT; + } + + @Override + public boolean isIsUint16Type() + { + return getKind() == Kind.KIND_USHORT; + } + + @Override + public boolean isIsInt32Type() + { + return getKind() == Kind.KIND_LONG; + } + + @Override + public boolean isIsUint32Type() + { + return getKind() == Kind.KIND_ULONG; + } + + @Override + public boolean isIsInt64Type() + { + return getKind() == Kind.KIND_LONGLONG; + } + + @Override + public boolean isIsUint64Type() + { + return getKind() == Kind.KIND_ULONGLONG; + } + + @Override + public boolean isIsFloat32Type() + { + return getKind() == Kind.KIND_FLOAT; + } + + @Override + public boolean isIsFloat64Type() + { + return getKind() == Kind.KIND_DOUBLE; + } + + @Override + public boolean isIsFloat128Type() + { + return getKind() == Kind.KIND_LONGDOUBLE; + } + } diff --git a/src/main/java/com/eprosima/idl/parser/typecode/SequenceTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/SequenceTypeCode.java index 3b12a196..3df81cef 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/SequenceTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/SequenceTypeCode.java @@ -39,6 +39,10 @@ public boolean isIsType_e() @Override public String getTypeIdentifier() { + if (isIsBounded() && Integer.parseInt(evaluated_maxsize_) >= 256) + { + return "TI_PLAIN_SEQUENCE_LARGE"; + } return "TI_PLAIN_SEQUENCE_SMALL"; } @@ -119,6 +123,7 @@ public String getMaxsize() return m_maxsize; } + @Override public String getEvaluatedMaxsize() { if (evaluated_maxsize_ == null) diff --git a/src/main/java/com/eprosima/idl/parser/typecode/StringTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/StringTypeCode.java index 7f1366be..2f17f3fe 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StringTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StringTypeCode.java @@ -42,9 +42,23 @@ public String getTypeIdentifier() switch (getKind()) { case Kind.KIND_STRING: - return "TI_STRING8_SMALL"; + if (isIsBounded() && Integer.parseInt(evaluated_maxsize_) >= 256) + { + return "TI_STRING8_LARGE"; + } + else + { + return "TI_STRING8_SMALL"; + } case Kind.KIND_WSTRING: - return "TI_STRING16_SMALL"; + if (isIsBounded() && Integer.parseInt(evaluated_maxsize_) >= 256) + { + return "TI_STRING16_LARGE"; + } + else + { + return "TI_STRING16_SMALL"; + } default: return "TK_None"; } @@ -96,6 +110,7 @@ public String getIdlTypename() return getIdlTypenameFromStringTemplate().toString(); } + @Override public String getMaxsize() { if (m_maxsize == null) @@ -106,6 +121,7 @@ public String getMaxsize() return m_maxsize; } + @Override public String getEvaluatedMaxsize() { if (evaluated_maxsize_ == null) diff --git a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java index c7520f1c..6c9944f0 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -22,6 +22,7 @@ import com.eprosima.idl.context.Context; import com.eprosima.idl.parser.exception.ParseException; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.tree.Annotation; import com.eprosima.idl.parser.tree.Inherits; @@ -163,6 +164,17 @@ public List getMembers( return allMembers; } + public Member getFirstMember() throws RuntimeGenerationException + { + List members = getMembers(); + if (members.size() == 0) + { + throw new RuntimeGenerationException("Error in structure " + super.getName() + + ": trying accesing first member of an empty structure"); + } + return members.get(0); + } + public List getAllMembers() // Alias for getMembers(true) for stg { return getMembers(true); @@ -238,6 +250,17 @@ public boolean addMember( return super.addMember(member); } + @Override + public boolean isNonForwardedContent() + { + boolean ret_code = true; + if (super_type_ != null) + { + ret_code &= super_type_.isNonForwardedContent(); + } + return ret_code &= super.isNonForwardedContent(); + } + @Override protected boolean check_unique_member_id( Member member) diff --git a/src/main/java/com/eprosima/idl/parser/typecode/TypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/TypeCode.java index b783626b..55d5c0b8 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/TypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/TypeCode.java @@ -14,16 +14,16 @@ package com.eprosima.idl.parser.typecode; -import com.eprosima.idl.parser.tree.Annotation; -import com.eprosima.idl.parser.tree.Notebook; -import com.eprosima.idl.context.Context; - -import java.util.Map; -import java.util.HashMap; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import org.stringtemplate.v4.ST; import org.stringtemplate.v4.STGroup; +import com.eprosima.idl.context.Context; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; +import com.eprosima.idl.parser.tree.Annotation; +import com.eprosima.idl.parser.tree.Notebook; public abstract class TypeCode implements Notebook @@ -161,6 +161,11 @@ public String getMaxsize() return null; } + public String getEvaluatedMaxsize() throws RuntimeGenerationException + { + throw new RuntimeGenerationException("Non-collection types does not have an evaluated max size"); + } + /*! * @brief This function returns the size of the datatype. By default is null string. * @return The size of the datatype. @@ -222,6 +227,76 @@ public boolean isIsType_13() return false; } + public boolean isIsBooleanType() + { + return false; + } + + public boolean isIsByteType() + { + return false; + } + + public boolean isIsInt8Type() + { + return false; + } + + public boolean isIsUint8Type() + { + return false; + } + + public boolean isIsInt16Type() + { + return false; + } + + public boolean isIsUint16Type() + { + return false; + } + + public boolean isIsInt32Type() + { + return false; + } + + public boolean isIsUint32Type() + { + return false; + } + + public boolean isIsInt64Type() + { + return false; + } + + public boolean isIsUint64Type() + { + return false; + } + + public boolean isIsFloat32Type() + { + return false; + } + + public boolean isIsFloat64Type() + { + return false; + } + + public boolean isIsFloat128Type() + { + return false; + } + + public boolean isIsEnumType() + { + return false; + } + public boolean isIsBitmaskType() { return false; @@ -242,12 +317,12 @@ public boolean isIsWStringType() return false; } - public boolean isIsWCharType() + public boolean isIsCharType() { return false; } - public boolean isIsEnumType() + public boolean isIsWCharType() { return false; } @@ -365,35 +440,42 @@ void calculate_extensibility( { if (ExtensibilityKind.NOT_APPLIED == extensibility_) { - if (m_annotations.containsKey(Annotation.final_str) || - (m_annotations.containsKey(Annotation.extensibility_str) && - m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_final_val))) + try { - extensibility_ = ExtensibilityKind.FINAL; - } - else if (m_annotations.containsKey(Annotation.appendable_str) || - (m_annotations.containsKey(Annotation.extensibility_str) && - m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_appendable_val))) - { - extensibility_ = ExtensibilityKind.APPENDABLE; - } - else if (m_annotations.containsKey(Annotation.mutable_str) || - (m_annotations.containsKey(Annotation.extensibility_str) && - m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_mutable_val))) - { - extensibility_ = ExtensibilityKind.MUTABLE; - } - else - { - if (ExtensibilityKind.NOT_APPLIED != base_ext) + if (m_annotations.containsKey(Annotation.final_str) || + (m_annotations.containsKey(Annotation.extensibility_str) && + m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_final_val))) + { + extensibility_ = ExtensibilityKind.FINAL; + } + else if (m_annotations.containsKey(Annotation.appendable_str) || + (m_annotations.containsKey(Annotation.extensibility_str) && + m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_appendable_val))) + { + extensibility_ = ExtensibilityKind.APPENDABLE; + } + else if (m_annotations.containsKey(Annotation.mutable_str) || + (m_annotations.containsKey(Annotation.extensibility_str) && + m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_mutable_val))) { - extensibility_ = base_ext; + extensibility_ = ExtensibilityKind.MUTABLE; } else { - extensibility_ = default_extensibility; + if (ExtensibilityKind.NOT_APPLIED != base_ext) + { + extensibility_ = base_ext; + } + else + { + extensibility_ = default_extensibility; + } } } + catch (RuntimeGenerationException ex) + { + // Should not be called as @extensibility annotation has only one parameter + } } } @@ -427,12 +509,49 @@ public boolean isAnnotationMutable() return ExtensibilityKind.MUTABLE == extensibility_; } + public boolean isAnnotationExtensibilityNotApplied() + { + if (!m_annotations.containsKey(Annotation.final_str) && + !m_annotations.containsKey(Annotation.appendable_str) && + !m_annotations.containsKey(Annotation.mutable_str) && + !m_annotations.containsKey(Annotation.extensibility_str)) + { + return true; + } + return false; + } + public boolean isAnnotationNested() { - Annotation ann = m_annotations.get("nested"); + Annotation ann = m_annotations.get(Annotation.nested_str); if (ann != null) { - return ann.getValue().toUpperCase().equals("TRUE"); + try + { + return ann.getValue().toUpperCase().equals(Annotation.capitalized_true_str); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @nested annotation has only one parameter + } + } + return false; + } + + public boolean isAnnotationAutoidHash() + { + Annotation ann = m_annotations.get(Annotation.autoid_str); + if (ann != null) + { + try + { + return (ann.getValue().toUpperCase().equals(Annotation.autoid_hash_value_str) || + ann.getValue().isEmpty()); + } + catch (RuntimeGenerationException ex) + { + // Should not be called as @autoid annotation has only one parameter + } } return false; } @@ -470,4 +589,5 @@ public void setDefined() private boolean m_defined = false; private ExtensibilityKind extensibility_ = ExtensibilityKind.NOT_APPLIED; + } diff --git a/src/main/java/com/eprosima/idl/parser/typecode/UnionMember.java b/src/main/java/com/eprosima/idl/parser/typecode/UnionMember.java index 5cbb2ecf..d2fadac8 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/UnionMember.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/UnionMember.java @@ -35,6 +35,11 @@ public List getLabels() return m_labels; } + public int getLabelsSize() + { + return m_labels.size(); + } + public void setLabels(List labels) { m_labels = labels; diff --git a/src/main/java/com/eprosima/solution/Project.java b/src/main/java/com/eprosima/solution/Project.java index c7e90e4e..d3bf69b1 100644 --- a/src/main/java/com/eprosima/solution/Project.java +++ b/src/main/java/com/eprosima/solution/Project.java @@ -30,6 +30,7 @@ public Project(String name, String file, LinkedHashSet dependencies) m_commonsrcfiles = new ArrayList(); m_commonincludefiles = new ArrayList(); m_commontestingfiles = new ArrayList(); + m_typeobjecttestingfiles = new ArrayList(); } public void setParent(Solution sol) @@ -82,6 +83,16 @@ public ArrayList getCommonTestingFiles() return m_commontestingfiles; } + public void addTypeObjectTestingFile(String file) + { + m_typeobjecttestingfiles.add(file); + } + + public ArrayList getTypeObjectTestingFiles() + { + return m_typeobjecttestingfiles; + } + /*! * @brief Used in string templates. */ @@ -135,6 +146,7 @@ public ArrayList getFullDependencies() private ArrayList m_commonsrcfiles = null; private ArrayList m_commonincludefiles = null; private ArrayList m_commontestingfiles = null; + private ArrayList m_typeobjecttestingfiles = null; private LinkedHashSet m_dependencies = null; String m_guid = null; Solution m_parent = null; diff --git a/src/main/java/com/eprosima/solution/Solution.java b/src/main/java/com/eprosima/solution/Solution.java index ff3d2757..dce12d1f 100644 --- a/src/main/java/com/eprosima/solution/Solution.java +++ b/src/main/java/com/eprosima/solution/Solution.java @@ -14,6 +14,7 @@ package com.eprosima.solution; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.log.ColorMessage; import java.util.ArrayList; @@ -105,6 +106,19 @@ public ArrayList getProjects() return m_cacheprojects; } + /*! + * @brief Only valid if one IDL is passed to Fast DDS-Gen. Used only in testing environment. + */ + public Project getMainProject() throws RuntimeGenerationException + { + ArrayList projects = getProjects(); + if (projects.isEmpty()) + { + throw new RuntimeGenerationException("Error: no projects have been defined"); + } + return (Project)projects.get(projects.size() - 1); + } + public boolean existsProject(String name) { boolean ret = false;