From f93daeb31d5455925d9faf891399aae3a467bdcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Mon, 4 Dec 2023 14:30:44 +0100 Subject: [PATCH 1/8] Refs #20084. Add index to Members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../eprosima/idl/parser/typecode/Member.java | 21 ++++++++++++++++++- .../idl/parser/typecode/MemberedTypeCode.java | 14 +++++++++++++ .../idl/parser/typecode/StructTypeCode.java | 5 +++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eprosima/idl/parser/typecode/Member.java b/src/main/java/com/eprosima/idl/parser/typecode/Member.java index 69c6d5a2..3098e746 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/Member.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/Member.java @@ -234,11 +234,30 @@ public int getId() return id_; } + /*! + * Sets the order of definition of the member. + * + * This function is intended to be called by MemberTypeCode.java. + */ + public void set_index(int index) + { + index_ = index; + } + + public int getIndex() + { + return index_; + } + private String m_name = null; private TypeCode m_typecode = null; private HashMap m_annotations = null; - private int id_ = 0xFFFFFFF; // MEMBER_ID_INVALID + private final int MEMBER_ID_INVALID = 0x0FFFFFFF; + + private int id_ = MEMBER_ID_INVALID; + + private int index_ = 0; } 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 395d97ed..9246564b 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -154,12 +154,24 @@ public boolean addMember(Member member) throws ParseException if(!m_members.containsKey(member.getName())) { + member.set_index(last_index++); + calculate_member_id_(member); m_members.put(member.getName(), member); return true; } + return false; } + /*! + * Derived classes can implement this function. By default do nothing. + * + * If implemented, this function should calculate the MemberId for the given member. + */ + protected void calculate_member_id_(Member member) + { + } + @Override public abstract String getCppTypename(); @@ -251,4 +263,6 @@ protected void check_annotation_for_aggregated_types( private String m_scope = null; private LinkedHashMap m_members = null; + + private int last_index = 0; } 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 3c9a8324..6ea1d3e5 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -229,6 +229,11 @@ public void addAnnotation( super.addAnnotation(ctx, annotation); } + @Override + protected void calculate_member_id_(Member member) + { + } + private StructTypeCode super_type_; protected boolean detect_recursive_ = false; From f52ac58e2edd1d4495d5abd6392a44eeeba09b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Mon, 4 Dec 2023 15:59:40 +0100 Subject: [PATCH 2/8] Refs #20084. Add @id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../eprosima/idl/parser/tree/Annotation.java | 3 ++ .../eprosima/idl/parser/typecode/Member.java | 33 +++++++++++-- .../idl/parser/typecode/MemberedTypeCode.java | 48 +++++++++++++++++-- .../idl/parser/typecode/StructTypeCode.java | 5 +- .../idl/parser/typecode/UnionTypeCode.java | 6 ++- 5 files changed, 84 insertions(+), 11 deletions(-) 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 6a70b738..8ea5b430 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/Annotation.java +++ b/src/main/java/com/eprosima/idl/parser/tree/Annotation.java @@ -20,6 +20,9 @@ public class Annotation { + public static final String hashid_str = "hashid"; + public static final String id_str = "id"; + public static final String final_str = "final"; public static final String appendable_str = "appendable"; public static final String mutable_str = "mutable"; diff --git a/src/main/java/com/eprosima/idl/parser/typecode/Member.java b/src/main/java/com/eprosima/idl/parser/typecode/Member.java index 3098e746..02c335cd 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/Member.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/Member.java @@ -14,6 +14,7 @@ package com.eprosima.idl.parser.typecode; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.tree.Annotation; import com.eprosima.idl.parser.tree.Notebook; import com.eprosima.idl.context.Context; @@ -224,7 +225,33 @@ public boolean isIsBounded() return false; } - public void setId(int id) + public boolean isAnnotationId() + { + return null != m_annotations.get(Annotation.id_str); + } + + public String getAnnotationIdValue() throws RuntimeGenerationException + { + Annotation ann = m_annotations.get(Annotation.id_str); + if (ann == null) + { + throw new RuntimeGenerationException("Error in member " + m_name + ": @id annotation not found."); + } + + return ann.getValue(); + } + + public boolean isAnnotationHashid() + { + return null != m_annotations.get(Annotation.hashid_str); + } + + /*! + * Sets the member's id. + * + * This function is intended to be called by MemberTypeCode. + */ + public void set_id(int id) { id_ = id; } @@ -237,7 +264,7 @@ public int getId() /*! * Sets the order of definition of the member. * - * This function is intended to be called by MemberTypeCode.java. + * This function is intended to be called by MemberTypeCode. */ public void set_index(int index) { @@ -255,7 +282,7 @@ public int getIndex() private HashMap m_annotations = null; - private final int MEMBER_ID_INVALID = 0x0FFFFFFF; + public static final int MEMBER_ID_INVALID = 0x0FFFFFFF; private int id_ = MEMBER_ID_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 9246564b..fd48aa83 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -19,6 +19,7 @@ import java.util.LinkedHashMap; import com.eprosima.idl.parser.exception.ParseException; +import com.eprosima.idl.parser.exception.RuntimeGenerationException; import com.eprosima.idl.parser.tree.Annotation; public abstract class MemberedTypeCode extends TypeCode @@ -91,7 +92,8 @@ public List getMembers() return new ArrayList(m_members.values()); } - public boolean addMember(Member member) throws ParseException + public boolean addMember( + Member member) throws ParseException { // Check annotations. if (member.isAnnotationOptional() && Kind.KIND_STRUCT != getKind()) @@ -151,11 +153,37 @@ public boolean addMember(Member member) throws ParseException throw new ParseException(null, "Error in member " + member.getName() + ": @key and @optional annotations are incompatible."); } + if (member.isAnnotationId() && ( + Kind.KIND_STRUCT != getKind() && Kind.KIND_UNION != getKind())) + { + throw new ParseException(null, "Error in member " + member.getName() + + ": @id annotations only supported for structure's members or union's members."); + } + if (member.isAnnotationHashid() && ( + Kind.KIND_STRUCT != getKind() && Kind.KIND_UNION != getKind())) + { + throw new ParseException(null, "Error in member " + member.getName() + + ": @id annotations only supported for structure's members or union's members."); + } + if (member.isAnnotationId() && member.isAnnotationHashid()) + { + throw new ParseException(null, "Error in member " + member.getName() + + ": @id and @hashid annotations cannot be together."); + } if(!m_members.containsKey(member.getName())) { + if (Member.MEMBER_ID_INVALID != member.getId()) + { + for(Member m : m_members.values()) + { + if (m.getId() == member.getId()) + { + return false; + } + } + } member.set_index(last_index++); - calculate_member_id_(member); m_members.put(member.getName(), member); return true; } @@ -164,12 +192,22 @@ public boolean addMember(Member member) throws ParseException } /*! - * Derived classes can implement this function. By default do nothing. - * - * If implemented, this function should calculate the MemberId for the given member. + * This function calculates the MemberId for the given member. + * Derived classes can use this function but it must be called from a override addMember(). */ protected void calculate_member_id_(Member member) { + if (member.isAnnotationId()) + { + try + { + member.set_id(Integer.parseInt(member.getAnnotationIdValue())); + } + catch (RuntimeGenerationException ex) + { + // Should be never called because was previously called isAnnotationId(); + } + } } @Override 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 6ea1d3e5..96b25698 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -230,8 +230,11 @@ public void addAnnotation( } @Override - protected void calculate_member_id_(Member member) + public boolean addMember( + Member member) throws ParseException { + calculate_member_id_(member); + return super.addMember(member); } private StructTypeCode super_type_; diff --git a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java index b7092645..23c79900 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java @@ -21,6 +21,7 @@ import org.stringtemplate.v4.ST; import com.eprosima.idl.context.Context; +import com.eprosima.idl.parser.exception.ParseException; import com.eprosima.idl.parser.tree.Annotation; @@ -72,7 +73,7 @@ public boolean isIsUnionType() * @return 0 is ok, -1 the member is repeated, -2 is another default member. */ public int addMember( - UnionMember member) + UnionMember member) throws ParseException { if (member.isDefault()) { @@ -113,7 +114,8 @@ public int addMember( member.setLabels(labels); member.setJavaLabels(javalabels); - if (!addMember((Member)member)) + calculate_member_id_(member); + if (!super.addMember(member)) { return -1; } From c8ce2047d4d7206b0dec823deb80630f6eca5126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Mon, 4 Dec 2023 16:17:20 +0100 Subject: [PATCH 3/8] Refs #20084. Good use of StructTypeCode super_type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../idl/parser/typecode/MemberedTypeCode.java | 40 ++++++++++++++----- .../idl/parser/typecode/StructTypeCode.java | 28 +++++++++++++ 2 files changed, 57 insertions(+), 11 deletions(-) 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 fd48aa83..82053da5 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -173,17 +173,15 @@ public boolean addMember( if(!m_members.containsKey(member.getName())) { - if (Member.MEMBER_ID_INVALID != member.getId()) + if (Member.MEMBER_ID_INVALID != member.getId() && !check_unique_member_id(member)) { - for(Member m : m_members.values()) - { - if (m.getId() == member.getId()) - { - return false; - } - } + return false; + } + member.set_index(last_index_++); + if (last_id_ < member.getId()) + { + last_id_ = member.getId(); } - member.set_index(last_index++); m_members.put(member.getName(), member); return true; } @@ -195,7 +193,8 @@ public boolean addMember( * This function calculates the MemberId for the given member. * Derived classes can use this function but it must be called from a override addMember(). */ - protected void calculate_member_id_(Member member) + protected void calculate_member_id_( + Member member) { if (member.isAnnotationId()) { @@ -210,6 +209,23 @@ protected void calculate_member_id_(Member member) } } + /*! + * This function check there is no other member with same id. + */ + protected boolean check_unique_member_id( + Member member) + { + for(Member m : m_members.values()) + { + if (m.getId() == member.getId()) + { + return false; + } + } + + return true; + } + @Override public abstract String getCppTypename(); @@ -302,5 +318,7 @@ protected void check_annotation_for_aggregated_types( private LinkedHashMap m_members = null; - private int last_index = 0; + private int last_index_ = 0; + + protected int last_id_ = 0; } 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 96b25698..92a54dd1 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -118,6 +118,8 @@ else if (super_type_ != null) { throw new ParseException(null, "Inheritance must correspond to the name of a previously defined structure"); } + + last_id_ = super_type_.last_id_; } @Override @@ -237,6 +239,32 @@ public boolean addMember( return super.addMember(member); } + @Override + protected boolean check_unique_member_id( + Member member) + { + if (super_type_ != null) + { + for (Member m : super_type_.getAllMembers()) + { + if (m.getId() == member.getId()) + { + return false; + } + } + } + + for (Member m : getMembers()) + { + if (m.getId() == member.getId()) + { + return false; + } + } + + return true; + } + private StructTypeCode super_type_; protected boolean detect_recursive_ = false; From d58e3acf0feacf3bcfbb75adc6ab6ad4e98db001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Mon, 4 Dec 2023 16:23:29 +0100 Subject: [PATCH 4/8] Refs #20084. Returning calculated id. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../idl/parser/typecode/StructTypeCode.java | 21 ------------------- 1 file changed, 21 deletions(-) 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 92a54dd1..8e2f37be 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -153,27 +153,6 @@ public List getAllMembers() // Alias for getMembers(true) for stg return getMembers(true); } - public List> getAllIdentifiedMembers() - { - int seq_id = 0; - List> ret_members = new ArrayList>(); - - if (super_type_ != null) - { - for (Member m : super_type_.getAllMembers()) - { - ret_members.add(new AbstractMap.SimpleEntry<>(seq_id++, m)); - } - } - - for (Member m : getMembers()) - { - ret_members.add(new AbstractMap.SimpleEntry<>(seq_id++, m)); - } - - return ret_members; - } - @Override public boolean isIsPlain() { From 4247e2afab0b5424be16812c68a7c4016d3c0990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Tue, 5 Dec 2023 07:57:52 +0100 Subject: [PATCH 5/8] Refs #20084. Using autoid(SEQUENTIAL). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../com/eprosima/idl/parser/grammar/IDL.g4 | 8 +--- .../com/eprosima/idl/context/Context.java | 17 ++++---- .../eprosima/idl/parser/tree/Annotation.java | 8 +++- .../eprosima/idl/parser/typecode/Member.java | 3 +- .../idl/parser/typecode/MemberedTypeCode.java | 39 +++++++++++++++---- .../idl/parser/typecode/StructTypeCode.java | 2 +- 6 files changed, 53 insertions(+), 24 deletions(-) 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 99126936..a72b29d9 100644 --- a/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 +++ b/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 @@ -1514,7 +1514,7 @@ struct_type returns [Pair, TemplateGroup> returnPair = null, St TypeCode scopedType = ctx.getTypeCode($scoped_name.pair.first()); if (scopedType instanceof StructTypeCode) { - parentStruct = (StructTypeCode)scopedType; + structTP.addInheritance(ctx, scopedType); } else { @@ -1540,10 +1540,6 @@ struct_type returns [Pair, TemplateGroup> returnPair = null, St vector = new Vector(); structTP.setForwarded(false); vector.add(structTP); - if (parentStruct != null) - { - structTP.addInheritance(ctx, parentStruct); - } $returnPair = new Pair, TemplateGroup>(vector, structTemplates); $fw_name = (fw_declaration) ? name : null; } @@ -1587,7 +1583,7 @@ member_list [StructTypeCode structTP] returns [TemplateGroup tg = null] if(pair.first().second() != null) { $tg = pair.first().second(); - } + } } } } diff --git a/src/main/java/com/eprosima/idl/context/Context.java b/src/main/java/com/eprosima/idl/context/Context.java index 3c391a3f..0d42524f 100644 --- a/src/main/java/com/eprosima/idl/context/Context.java +++ b/src/main/java/com/eprosima/idl/context/Context.java @@ -173,14 +173,14 @@ public Context( } // Add here builtin annotations? (IDL 4.2 - 8.3.1 section) - AnnotationDeclaration idann = createAnnotationDeclaration("id", null); + AnnotationDeclaration idann = createAnnotationDeclaration(Annotation.id_str, null); idann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_LONG), "-1")); - AnnotationDeclaration autoidann = createAnnotationDeclaration("autoid", null); - EnumTypeCode autoidannenum = new EnumTypeCode(autoidann.getScopedname(), "autoidannenum"); - autoidannenum.addMember(new EnumMember("SEQUENTIAL")); - autoidannenum.addMember(new EnumMember("HASH")); - autoidann.addMember(new AnnotationMember("value", autoidannenum, autoidannenum.getInitialValue())); + AnnotationDeclaration autoidann = createAnnotationDeclaration(Annotation.autoid_str, null); + EnumTypeCode autoidannenum = new EnumTypeCode(autoidann.getScopedname(), Annotation.autoid_enum_str); + autoidannenum.addMember(new EnumMember(Annotation.autoid_sequential_str)); + autoidannenum.addMember(new EnumMember(Annotation.autoid_hash_str)); + autoidann.addMember(new AnnotationMember("value", autoidannenum, Annotation.autoid_hash_str)); AnnotationDeclaration optionalann = createAnnotationDeclaration("optional", null); optionalann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); @@ -192,7 +192,7 @@ public Context( valueann.addMember(new AnnotationMember("value", new AnyTypeCode(), null)); AnnotationDeclaration extensibilityann = createAnnotationDeclaration(Annotation.extensibility_str, null); - EnumTypeCode extensibilityannenum = new EnumTypeCode(extensibilityann.getScopedname(), "extensibilityannenum"); + EnumTypeCode extensibilityannenum = new EnumTypeCode(extensibilityann.getScopedname(), Annotation.extensibility_enum_str); extensibilityannenum.addMember(new EnumMember(Annotation.ex_final_str)); extensibilityannenum.addMember(new EnumMember(Annotation.ex_appendable_str)); extensibilityannenum.addMember(new EnumMember(Annotation.ex_mutable_str)); @@ -262,6 +262,9 @@ public Context( AnnotationDeclaration amiann = createAnnotationDeclaration("ami", null); amiann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + AnnotationDeclaration hashid_annotation = createAnnotationDeclaration(Annotation.hashid_str, null); + hashid_annotation.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_STRING), "")); + // Create default @non_serialized annotation. AnnotationDeclaration non_serializedann = createAnnotationDeclaration("non_serialized", null); non_serializedann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); 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 8ea5b430..8fcb7c1b 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/Annotation.java +++ b/src/main/java/com/eprosima/idl/parser/tree/Annotation.java @@ -20,13 +20,19 @@ public class Annotation { + 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_hash_str = "HASH"; + public static final String hashid_str = "hashid"; public static final String id_str = "id"; + public static final String extensibility_str = "extensibility"; + public static final String extensibility_enum_str = "ExtensibilityKind"; public static final String final_str = "final"; public static final String appendable_str = "appendable"; public static final String mutable_str = "mutable"; - public static final String extensibility_str = "extensibility"; public static final String ex_final_str = "FINAL"; public static final String ex_appendable_str = "APPENDABLE"; public static final String ex_mutable_str = "MUTABLE"; diff --git a/src/main/java/com/eprosima/idl/parser/typecode/Member.java b/src/main/java/com/eprosima/idl/parser/typecode/Member.java index 02c335cd..450715f6 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/Member.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/Member.java @@ -235,7 +235,8 @@ public String getAnnotationIdValue() throws RuntimeGenerationException Annotation ann = m_annotations.get(Annotation.id_str); if (ann == null) { - throw new RuntimeGenerationException("Error in member " + m_name + ": @id annotation not found."); + throw new RuntimeGenerationException("Error in member " + m_name + ": @" + Annotation.id_str + + " annotation not found."); } return ann.getValue(); 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 82053da5..baeba11f 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -157,25 +157,27 @@ public boolean addMember( Kind.KIND_STRUCT != getKind() && Kind.KIND_UNION != getKind())) { throw new ParseException(null, "Error in member " + member.getName() + - ": @id annotations only supported for structure's members or union's members."); + ": @" + Annotation.id_str + + " annotations only supported for structure's members or union's members."); } if (member.isAnnotationHashid() && ( Kind.KIND_STRUCT != getKind() && Kind.KIND_UNION != getKind())) { throw new ParseException(null, "Error in member " + member.getName() + - ": @id annotations only supported for structure's members or union's members."); + ": @" + Annotation.hashid_str + + "annotations only supported for structure's members or union's members."); } if (member.isAnnotationId() && member.isAnnotationHashid()) { throw new ParseException(null, "Error in member " + member.getName() + - ": @id and @hashid annotations cannot be together."); + ": @" + Annotation.id_str + " and @" + Annotation.hashid_str + " annotations cannot be together."); } if(!m_members.containsKey(member.getName())) { if (Member.MEMBER_ID_INVALID != member.getId() && !check_unique_member_id(member)) { - return false; + throw new ParseException(null, member.getName() + " has a MemberId already in use."); } member.set_index(last_index_++); if (last_id_ < member.getId()) @@ -196,17 +198,21 @@ public boolean addMember( protected void calculate_member_id_( Member member) { - if (member.isAnnotationId()) + try { - try + if (member.isAnnotationId()) { member.set_id(Integer.parseInt(member.getAnnotationIdValue())); } - catch (RuntimeGenerationException ex) + else if (!isAnnotationAutoid() || getAnnotationAutoidValue().equals(Annotation.autoid_sequential_str)) { - // Should be never called because was previously called isAnnotationId(); + member.set_id(++last_id_); } } + catch (RuntimeGenerationException ex) + { + // Should be never called because was previously called isAnnotationId() or similar. + } } /*! @@ -312,6 +318,23 @@ protected void check_annotation_for_aggregated_types( } } + public boolean isAnnotationAutoid() + { + return null != getAnnotations().get(Annotation.autoid_str); + } + + public String getAnnotationAutoidValue() throws RuntimeGenerationException + { + Annotation ann = getAnnotations().get(Annotation.autoid_str); + if (ann == null) + { + throw new RuntimeGenerationException("Error in member " + m_name + ": @" + Annotation.autoid_str + + " annotation not found."); + } + + return ann.getValue(); + } + private String m_name = null; private String m_scope = 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 8e2f37be..7116a183 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -222,7 +222,7 @@ public boolean addMember( protected boolean check_unique_member_id( Member member) { - if (super_type_ != null) + if (null != super_type_) { for (Member m : super_type_.getAllMembers()) { From 4737b5b8b93393c5bf69277bf0a63221eab2ddd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Tue, 5 Dec 2023 11:22:57 +0100 Subject: [PATCH 6/8] Refs #20084. Using autoid(HASH) and hashid. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../com/eprosima/idl/parser/grammar/IDL.g4 | 37 ++++++++++++++--- .../com/eprosima/idl/context/Context.java | 2 +- .../eprosima/idl/parser/tree/Annotation.java | 1 + .../eprosima/idl/parser/typecode/Member.java | 25 ++++++++++- .../idl/parser/typecode/MemberedTypeCode.java | 41 +++++++++++++++---- .../idl/parser/typecode/StructTypeCode.java | 4 +- .../idl/parser/typecode/UnionTypeCode.java | 10 ++--- 7 files changed, 97 insertions(+), 23 deletions(-) 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 a72b29d9..ad96b671 100644 --- a/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 +++ b/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 @@ -769,8 +769,8 @@ type_decl [Vector annotations, ArrayList defs] returns [ String fw_name = null; } : ( KW_TYPEDEF {tk = _input.LT(1);} type_declarator[null] { ttg=$type_declarator.returnPair; } - | struct_type { ttg=$struct_type.returnPair; fw_name = $struct_type.fw_name; } - | union_type[defs] { ttg=$union_type.returnPair; fw_name = $union_type.fw_name; } + | struct_type[annotations] { ttg=$struct_type.returnPair; fw_name = $struct_type.fw_name; } + | union_type[annotations, defs] { ttg=$union_type.returnPair; fw_name = $union_type.fw_name; } | enum_type { ttg=$enum_type.returnPair; } | bitset_type { ttg=$bitset_type.returnPair; } | bitmask_type { ttg=$bitmask_type.returnPair; } @@ -950,8 +950,8 @@ template_type_spec returns [Pair returnPair = null] ; constr_type_spec returns [Pair, TemplateGroup> returnPair = null] - : struct_type - | union_type[null] + : struct_type[null] + | union_type[null, null] | enum_type | bitset_type | bitmask_type @@ -1458,7 +1458,7 @@ bit_values [BitmaskTypeCode owner] )* ; -struct_type returns [Pair, TemplateGroup> returnPair = null, String fw_name = null] +struct_type[Vector annotations] returns [Pair, TemplateGroup> returnPair = null, String fw_name = null] @init{ String name = null; Vector vector = null; @@ -1508,6 +1508,18 @@ struct_type returns [Pair, TemplateGroup> returnPair = null, St structTP = ctx.createStructTypeCode(name); } structTP.setDefined(); + + // Apply annotations to the TypeCode + if (null != annotations) + { + for(Annotation annotation : annotations) + { + if (annotation != null) // Some annotations may be ignored + { + structTP.addAnnotation(ctx, annotation); + } + } + } } (COLON scoped_name { @@ -1663,7 +1675,7 @@ member returns [Vector, TemplateGroup>, Member>> r } ; -union_type [ArrayList defs] returns [Pair, TemplateGroup> returnPair = null, String fw_name = null] +union_type [Vector annotations, ArrayList defs] returns [Pair, TemplateGroup> returnPair = null, String fw_name = null] @init { String name = null; int line = 0; @@ -1722,6 +1734,19 @@ union_type [ArrayList defs] returns [Pair, Template unionTP = ctx.createUnionTypeCode(ctx.getScope(), name, dist_type); } unionTP.setDefined(); + + // Apply annotations to the TypeCode + if (null != annotations) + { + for(Annotation annotation : annotations) + { + if (annotation != null) // Some annotations may be ignored + { + unionTP.addAnnotation(ctx, annotation); + } + } + } + line= _input.LT(1) != null ? _input.LT(1).getLine() - ctx.getCurrentIncludeLine() : 1; } LEFT_BRACE switch_body[unionTP] RIGHT_BRACE diff --git a/src/main/java/com/eprosima/idl/context/Context.java b/src/main/java/com/eprosima/idl/context/Context.java index 0d42524f..07715c87 100644 --- a/src/main/java/com/eprosima/idl/context/Context.java +++ b/src/main/java/com/eprosima/idl/context/Context.java @@ -263,7 +263,7 @@ public Context( amiann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); AnnotationDeclaration hashid_annotation = createAnnotationDeclaration(Annotation.hashid_str, null); - hashid_annotation.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_STRING), "")); + hashid_annotation.addMember(new AnnotationMember("value", new StringTypeCode(Kind.KIND_STRING, null, null), "")); // Create default @non_serialized annotation. AnnotationDeclaration non_serializedann = createAnnotationDeclaration("non_serialized", null); 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 8fcb7c1b..d1e0f738 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/Annotation.java +++ b/src/main/java/com/eprosima/idl/parser/tree/Annotation.java @@ -23,6 +23,7 @@ public class Annotation 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 hashid_str = "hashid"; diff --git a/src/main/java/com/eprosima/idl/parser/typecode/Member.java b/src/main/java/com/eprosima/idl/parser/typecode/Member.java index 450715f6..5d86762c 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/Member.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/Member.java @@ -247,6 +247,18 @@ public boolean isAnnotationHashid() return null != m_annotations.get(Annotation.hashid_str); } + public String getAnnotationHashidValue() throws RuntimeGenerationException + { + Annotation ann = m_annotations.get(Annotation.hashid_str); + if (ann == null) + { + throw new RuntimeGenerationException("Error in member " + m_name + ": @" + Annotation.hashid_str + + " annotation not found."); + } + + return ann.getValue(); + } + /*! * Sets the member's id. * @@ -257,11 +269,22 @@ public void set_id(int id) id_ = id; } - public int getId() + /*! + * Return the MemberId as Integer. + */ + public int get_id() { return id_; } + /*! + * Return the MemberId as String in hexadecimal format. + */ + public String getId() + { + return String.format("0x%08x", id_); + } + /*! * Sets the order of definition of the member. * 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 baeba11f..3a11cffd 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -14,9 +14,11 @@ package com.eprosima.idl.parser.typecode; -import java.util.List; +import java.security.MessageDigest; import java.util.ArrayList; +import java.util.function.Function; import java.util.LinkedHashMap; +import java.util.List; import com.eprosima.idl.parser.exception.ParseException; import com.eprosima.idl.parser.exception.RuntimeGenerationException; @@ -175,15 +177,12 @@ public boolean addMember( if(!m_members.containsKey(member.getName())) { - if (Member.MEMBER_ID_INVALID != member.getId() && !check_unique_member_id(member)) + if (Member.MEMBER_ID_INVALID != member.get_id() && !check_unique_member_id(member)) { throw new ParseException(null, member.getName() + " has a MemberId already in use."); } member.set_index(last_index_++); - if (last_id_ < member.getId()) - { - last_id_ = member.getId(); - } + last_id_ = member.get_id(); m_members.put(member.getName(), member); return true; } @@ -198,16 +197,42 @@ public boolean addMember( protected void calculate_member_id_( Member member) { + Function calculate_hash = (String member_name) -> + { + int hash_id = 0; + try { + byte[] bytes = member_name.getBytes("UTF-8"); + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] md5 = md.digest(bytes); + hash_id = ((md5[3] & 0xFF) << 24) + ((md5[2] & 0xFF) << 16) + ((md5[1] & 0xFF) << 8) + (md5[0] & 0xFF); + hash_id &= 0x0FFFFFFF; + } + catch(Exception e) + { + e.printStackTrace(); + } + return hash_id; + }; + try { if (member.isAnnotationId()) { member.set_id(Integer.parseInt(member.getAnnotationIdValue())); } - else if (!isAnnotationAutoid() || getAnnotationAutoidValue().equals(Annotation.autoid_sequential_str)) + else if (member.isAnnotationHashid()) + { + String value = member.getAnnotationHashidValue(); + member.set_id(calculate_hash.apply(value.isEmpty() ? member.getName() : value)); + } + else if (!isAnnotationAutoid() || getAnnotationAutoidValue().equals(Annotation.autoid_sequential_value_str)) { member.set_id(++last_id_); } + else + { + member.set_id(calculate_hash.apply(member.getName())); + } } catch (RuntimeGenerationException ex) { @@ -223,7 +248,7 @@ protected boolean check_unique_member_id( { for(Member m : m_members.values()) { - if (m.getId() == member.getId()) + if (m.get_id() == member.get_id()) { return false; } 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 7116a183..c1dec3ac 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -226,7 +226,7 @@ protected boolean check_unique_member_id( { for (Member m : super_type_.getAllMembers()) { - if (m.getId() == member.getId()) + if (m.get_id() == member.get_id()) { return false; } @@ -235,7 +235,7 @@ protected boolean check_unique_member_id( for (Member m : getMembers()) { - if (m.getId() == member.getId()) + if (m.get_id() == member.get_id()) { return false; } diff --git a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java index 23c79900..6ef2e69c 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java @@ -224,21 +224,21 @@ public boolean isIsPlain() } // Add member and the default one at the end. - public List> getIdentifiedMembers() + public List getMembersDefaultAtEnd() { int position = 0; - List> ret_members = new ArrayList>(); - AbstractMap.SimpleEntry default_member = null; + List ret_members = new ArrayList(); + Member default_member = null; for (Member m : getMembers()) { if (position == m_defaultindex) { - default_member = new AbstractMap.SimpleEntry<>(position++, m); + default_member = m; } else { - ret_members.add(new AbstractMap.SimpleEntry<>(position++, m)); + ret_members.add(m); } } From 6ce2e7196ca5a306813beffcd11de70df6965173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Thu, 7 Dec 2023 11:22:40 +0100 Subject: [PATCH 7/8] Refs #20084. Fix applying annotations to struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../com/eprosima/idl/parser/grammar/IDL.g4 | 85 +++++++++++++------ .../com/eprosima/idl/context/Context.java | 2 +- .../eprosima/idl/parser/tree/Annotation.java | 4 + .../idl/parser/tree/TypeDeclaration.java | 11 +-- .../idl/parser/typecode/MemberedTypeCode.java | 8 +- .../idl/parser/typecode/StructTypeCode.java | 12 +++ .../idl/parser/typecode/TypeCode.java | 44 ++++++---- .../idl/parser/typecode/UnionTypeCode.java | 2 + 8 files changed, 117 insertions(+), 51 deletions(-) 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 ad96b671..84fc7a4f 100644 --- a/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 +++ b/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 @@ -768,12 +768,12 @@ type_decl [Vector annotations, ArrayList defs] returns [ Token tk = null; String fw_name = null; } - : ( KW_TYPEDEF {tk = _input.LT(1);} type_declarator[null] { ttg=$type_declarator.returnPair; } + : ( KW_TYPEDEF {tk = _input.LT(1);} type_declarator[null, annotations] { ttg=$type_declarator.returnPair; } | struct_type[annotations] { ttg=$struct_type.returnPair; fw_name = $struct_type.fw_name; } | union_type[annotations, defs] { ttg=$union_type.returnPair; fw_name = $union_type.fw_name; } - | enum_type { ttg=$enum_type.returnPair; } - | bitset_type { ttg=$bitset_type.returnPair; } - | bitmask_type { ttg=$bitmask_type.returnPair; } + | enum_type[annotations] { ttg=$enum_type.returnPair; } + | bitset_type[annotations] { ttg=$bitset_type.returnPair; } + | bitmask_type[annotations] { ttg=$bitmask_type.returnPair; } | KW_NATIVE { System.out.println("WARNING (File " + ctx.getFilename() + ", Line " + (_input.LT(1) != null ? _input.LT(1).getLine() - ctx.getCurrentIncludeLine() : "1") + "): Native declarations are not supported. Ignoring..."); } simple_declarator | constr_forward_decl ) { @@ -798,16 +798,6 @@ type_decl [Vector annotations, ArrayList defs] returns [ } TypeDeclaration typedeclaration = (fw_name == null) ? new TypeDeclaration(ctx.getScopeFile(), ctx.isInScopedFile(), ctx.getScope(), name, ttg.first().get(count), tk) : ctx.getTypeDeclaration(fw_name); - //System.out.println("Type ttg not null: " + name); - - // Add annotations - for(Annotation annotation : annotations) - { - if (annotation != null) // Some annotations may be ignored - { - typedeclaration.addAnnotation(ctx, annotation); - } - } // Add type declaration to the map with all typedeclarations. if (fw_name == null) @@ -823,7 +813,7 @@ type_decl [Vector annotations, ArrayList defs] returns [ } ; -type_declarator [AnnotationDeclaration annotation] returns [Pair, TemplateGroup> returnPair = null] +type_declarator [AnnotationDeclaration annotation, Vector annotations] returns [Pair, TemplateGroup> returnPair = null] @init { Vector vector = null; AliasTypeCode typedefTypecode = null; @@ -856,6 +846,18 @@ type_declarator [AnnotationDeclaration annotation] returns [Pair returnPair = null] constr_type_spec returns [Pair, TemplateGroup> returnPair = null] : struct_type[null] | union_type[null, null] - | enum_type - | bitset_type - | bitmask_type + | enum_type[null] + | bitset_type[null] + | bitmask_type[null] ; declarators returns [Vector, ContainerTypeCode>, TemplateGroup>> ret = new Vector, ContainerTypeCode>, TemplateGroup>>()] @@ -1245,7 +1247,7 @@ annotation_body [AnnotationDeclaration annotation] : ( annotation_member[annotation] - | enum_type SEMICOLON + | enum_type[null] SEMICOLON { pairtype = $enum_type.returnPair; $annotation.addEnums(pairtype.first()); @@ -1255,7 +1257,7 @@ annotation_body [AnnotationDeclaration annotation] pairconst = $const_decl.returnPair; $annotation.addConstDecl(pairconst.first()); } - | KW_TYPEDEF type_declarator[annotation] SEMICOLON + | KW_TYPEDEF type_declarator[annotation, null] SEMICOLON { pairtype = $type_declarator.returnPair; $annotation.addTypeDefs(pairtype.first()); @@ -1283,7 +1285,7 @@ annotation_forward_dcl KW_AT_ANNOTATION scoped_name ; -bitset_type returns [Pair, TemplateGroup> returnPair = null] +bitset_type[Vector annotations] returns [Pair, TemplateGroup> returnPair = null] @init { String name = null; Vector vector = null; @@ -1300,6 +1302,18 @@ bitset_type returns [Pair, TemplateGroup> returnPair = null] } name = ctx.removeEscapeCharacter($identifier.id); typecode = ctx.createBitsetTypeCode(ctx.getScope(), name); + + // Apply annotations to the TypeCode + if (null != annotations) + { + for(Annotation annotation : annotations) + { + if (annotation != null) // Some annotations may be ignored + { + typecode.addAnnotation(ctx, annotation); + } + } + } } ( COLON scoped_name { @@ -1394,7 +1408,7 @@ bitfield_spec returns [BitfieldSpec bitfieldType = null] } ; -bitmask_type returns [Pair, TemplateGroup> returnPair = null] +bitmask_type[Vector annotations] returns [Pair, TemplateGroup> returnPair = null] @init { String name = null; Vector vector = null; @@ -1410,6 +1424,18 @@ bitmask_type returns [Pair, TemplateGroup> returnPair = null] } name = ctx.removeEscapeCharacter($identifier.id); typecode = ctx.createBitmaskTypeCode(ctx.getScope(), name); + + // Apply annotations to the TypeCode + if (null != annotations) + { + for(Annotation annotation : annotations) + { + if (annotation != null) // Some annotations may be ignored + { + typecode.addAnnotation(ctx, annotation); + } + } + } } LEFT_BRACE bit_values[typecode] RIGHT_BRACE { @@ -1810,7 +1836,6 @@ switch_type_spec returns [TypeCode typecode = null] | wide_char_type { $typecode = $wide_char_type.typecode; } | octet_type { $typecode=$octet_type.typecode; } | boolean_type { $typecode=$boolean_type.typecode; } - | enum_type | scoped_name { pair=$scoped_name.pair; @@ -1926,7 +1951,7 @@ element_spec [List labels, boolean isDefault] returns [Pair, TemplateGroup> returnPair = null] +enum_type[Vector annotations] returns [Pair, TemplateGroup> returnPair = null] @init{ String name = null; Vector vector = null; @@ -1943,6 +1968,18 @@ enum_type returns [Pair, TemplateGroup> returnPair = null] } name = ctx.removeEscapeCharacter($identifier.id); enumTP = ctx.createEnumTypeCode(ctx.getScope(), name); + + // Apply annotations to the TypeCode + if (null != annotations) + { + for(Annotation annotation : annotations) + { + if (annotation != null) // Some annotations may be ignored + { + enumTP.addAnnotation(ctx, annotation); + } + } + } } LEFT_BRACE enumerator_list[enumTP] RIGHT_BRACE { diff --git a/src/main/java/com/eprosima/idl/context/Context.java b/src/main/java/com/eprosima/idl/context/Context.java index 07715c87..e9c31451 100644 --- a/src/main/java/com/eprosima/idl/context/Context.java +++ b/src/main/java/com/eprosima/idl/context/Context.java @@ -204,7 +204,7 @@ public Context( createAnnotationDeclaration(Annotation.mutable_str, null); // Create default @Key annotation. - AnnotationDeclaration keyann = createAnnotationDeclaration("key", null); + AnnotationDeclaration keyann = createAnnotationDeclaration("" + Annotation.key_str + "", null); keyann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); AnnotationDeclaration mustundann = createAnnotationDeclaration("must_understand", null); 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 d1e0f738..f88a12ae 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/Annotation.java +++ b/src/main/java/com/eprosima/idl/parser/tree/Annotation.java @@ -28,6 +28,7 @@ public class Annotation 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 extensibility_str = "extensibility"; public static final String extensibility_enum_str = "ExtensibilityKind"; @@ -35,8 +36,11 @@ public class Annotation public static final String appendable_str = "appendable"; public static final String mutable_str = "mutable"; public static final String ex_final_str = "FINAL"; + public static final String ex_final_val = "0"; public static final String ex_appendable_str = "APPENDABLE"; + public static final String ex_appendable_val = "1"; public static final String ex_mutable_str = "MUTABLE"; + public static final String ex_mutable_val = "2"; public Annotation(AnnotationDeclaration declaration) { diff --git a/src/main/java/com/eprosima/idl/parser/tree/TypeDeclaration.java b/src/main/java/com/eprosima/idl/parser/tree/TypeDeclaration.java index 9fb7c9fc..68caaea0 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/TypeDeclaration.java +++ b/src/main/java/com/eprosima/idl/parser/tree/TypeDeclaration.java @@ -28,13 +28,10 @@ public TypeDeclaration(String scopeFile, boolean isInScope, String scope, String m_typecode = typecode; // Set as parent to the Typecode. m_typecode.setParent(this); - } - - @Override - public void addAnnotation(Context ctx, Annotation annotation) - { - super.addAnnotation(ctx, annotation); - m_typecode.addAnnotation(ctx, annotation); // The TypeObject may interpret the annotation directly + for(Annotation annotation : typecode.getAnnotationList()) + { + addAnnotation(null, annotation); + } } public TypeCode getTypeCode() 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 3a11cffd..7f365a7f 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -122,7 +122,7 @@ public boolean addMember( if (member.isAnnotationKey() && Kind.KIND_STRUCT != getKind()) { throw new ParseException(null, "Error in member " + member.getName() + - ": @key annotations only supported for structure's members."); + ": @" + Annotation.key_str + " annotations only supported for structure's members."); } if (null != member.getAnnotationBitBound() && ( Kind.KIND_ENUM != getKind() && Kind.KIND_BITMASK != getKind())) @@ -148,12 +148,12 @@ public boolean addMember( if(member.isAnnotationKey() && member.isAnnotationNonSerialized()) { throw new ParseException(null, "Error in member " + member.getName() + - ": @key and @non_serialized annotations are incompatible."); + ": @" + Annotation.key_str + " and @non_serialized annotations are incompatible."); } if(member.isAnnotationKey() && member.isAnnotationOptional()) { throw new ParseException(null, "Error in member " + member.getName() + - ": @key and @optional annotations are incompatible."); + ": @" + Annotation.key_str + " and @optional annotations are incompatible."); } if (member.isAnnotationId() && ( Kind.KIND_STRUCT != getKind() && Kind.KIND_UNION != getKind())) @@ -366,7 +366,7 @@ public String getAnnotationAutoidValue() throws RuntimeGenerationException private LinkedHashMap m_members = null; - private int last_index_ = 0; + protected int last_index_ = 0; protected int last_id_ = 0; } 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 c1dec3ac..c46e4706 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/StructTypeCode.java @@ -119,7 +119,14 @@ else if (super_type_ != null) throw new ParseException(null, "Inheritance must correspond to the name of a previously defined structure"); } + last_id_ = super_type_.last_id_; + last_index_ = super_type_.last_index_; + if (get_extensibility(super_type_.get_extensibility()) != super_type_.get_extensibility()) + { + throw new ParseException(null, "Base structure and derived structure must have same " + + Annotation.extensibility_enum_str); + } } @Override @@ -214,6 +221,11 @@ public void addAnnotation( public boolean addMember( Member member) throws ParseException { + if (member.isAnnotationKey() && null != super_type_) + { + throw new ParseException(null, "Error in member " + member.getName() + + ": @" + Annotation.key_str + " cannot be used in a derived structure."); + } calculate_member_id_(member); return super.addMember(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 dce4f1d3..6707c208 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/TypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/TypeCode.java @@ -360,56 +360,70 @@ public Collection getAnnotationList() return m_annotations.values(); } - void calculate_extensibility() + void calculate_extensibility( + ExtensibilityKind base_ext) { if (ExtensibilityKind.NOT_APPLIED == extensibility_) { - if (null != m_annotations.get(Annotation.final_str) || - (null != m_annotations.get(Annotation.extensibility_str) && - m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_final_str))) + 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 (null != m_annotations.get(Annotation.appendable_str) || - (null != m_annotations.get(Annotation.extensibility_str) && - m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_appendable_str))) + 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 (null != m_annotations.get(Annotation.mutable_str) || - (null != m_annotations.get(Annotation.extensibility_str) && - m_annotations.get(Annotation.extensibility_str).getValue().equals(Annotation.ex_mutable_str))) + 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 { - extensibility_ = default_extensibility; + if (ExtensibilityKind.NOT_APPLIED != base_ext) + { + extensibility_ = base_ext; + } + else + { + extensibility_ = default_extensibility; + } } } } public ExtensibilityKind get_extensibility() { - calculate_extensibility(); + return get_extensibility(ExtensibilityKind.NOT_APPLIED); + } + + public ExtensibilityKind get_extensibility( + ExtensibilityKind base_ext) + { + calculate_extensibility(base_ext); return extensibility_; } public boolean isAnnotationFinal() { - calculate_extensibility(); + calculate_extensibility(ExtensibilityKind.NOT_APPLIED); return ExtensibilityKind.FINAL == extensibility_; } public boolean isAnnotationAppendable() { - calculate_extensibility(); + calculate_extensibility(ExtensibilityKind.NOT_APPLIED); return ExtensibilityKind.APPENDABLE == extensibility_; } public boolean isAnnotationMutable() { - calculate_extensibility(); + calculate_extensibility(ExtensibilityKind.NOT_APPLIED); return ExtensibilityKind.MUTABLE == extensibility_; } diff --git a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java index 6ef2e69c..b2a6eb7e 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java @@ -43,12 +43,14 @@ public UnionTypeCode( { super(Kind.KIND_UNION, scope, name); m_discriminatorTypeCode = discriminatorTypeCode; + ++last_index_; } public void setDiscriminatorType( TypeCode discriminatorTypeCode) { m_discriminatorTypeCode = discriminatorTypeCode; + ++last_index_; } @Override From 7a2f44fe3738af82d22ff5e7f2ee193d1df9340b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez=20Moreno?= Date: Mon, 11 Dec 2023 10:55:20 +0100 Subject: [PATCH 8/8] Refs #20084. Applying suggestions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ricardo González Moreno --- .../com/eprosima/idl/context/Context.java | 42 +++++++++---------- .../eprosima/idl/parser/tree/Annotation.java | 2 + .../idl/parser/typecode/MemberedTypeCode.java | 6 +-- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/eprosima/idl/context/Context.java b/src/main/java/com/eprosima/idl/context/Context.java index e9c31451..9a9dbb5b 100644 --- a/src/main/java/com/eprosima/idl/context/Context.java +++ b/src/main/java/com/eprosima/idl/context/Context.java @@ -174,29 +174,29 @@ public Context( // Add here builtin annotations? (IDL 4.2 - 8.3.1 section) AnnotationDeclaration idann = createAnnotationDeclaration(Annotation.id_str, null); - idann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_LONG), "-1")); + idann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_LONG), "-1")); AnnotationDeclaration autoidann = createAnnotationDeclaration(Annotation.autoid_str, null); EnumTypeCode autoidannenum = new EnumTypeCode(autoidann.getScopedname(), Annotation.autoid_enum_str); autoidannenum.addMember(new EnumMember(Annotation.autoid_sequential_str)); autoidannenum.addMember(new EnumMember(Annotation.autoid_hash_str)); - autoidann.addMember(new AnnotationMember("value", autoidannenum, Annotation.autoid_hash_str)); + autoidann.addMember(new AnnotationMember(Annotation.value_str, autoidannenum, Annotation.autoid_hash_str)); AnnotationDeclaration optionalann = createAnnotationDeclaration("optional", null); - optionalann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + optionalann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); AnnotationDeclaration positionann = createAnnotationDeclaration("position", null); - positionann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_USHORT), "-1")); + positionann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_USHORT), "-1")); - AnnotationDeclaration valueann = createAnnotationDeclaration("value", null); - valueann.addMember(new AnnotationMember("value", new AnyTypeCode(), null)); + AnnotationDeclaration valueann = createAnnotationDeclaration(Annotation.value_str, null); + valueann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); AnnotationDeclaration extensibilityann = createAnnotationDeclaration(Annotation.extensibility_str, null); EnumTypeCode extensibilityannenum = new EnumTypeCode(extensibilityann.getScopedname(), Annotation.extensibility_enum_str); extensibilityannenum.addMember(new EnumMember(Annotation.ex_final_str)); extensibilityannenum.addMember(new EnumMember(Annotation.ex_appendable_str)); extensibilityannenum.addMember(new EnumMember(Annotation.ex_mutable_str)); - extensibilityann.addMember(new AnnotationMember("value", extensibilityannenum, + extensibilityann.addMember(new AnnotationMember(Annotation.value_str, extensibilityannenum, extensibilityannenum.getInitialValue())); createAnnotationDeclaration(Annotation.final_str, null); @@ -204,11 +204,11 @@ public Context( createAnnotationDeclaration(Annotation.mutable_str, null); // Create default @Key annotation. - AnnotationDeclaration keyann = createAnnotationDeclaration("" + Annotation.key_str + "", null); - keyann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + AnnotationDeclaration keyann = createAnnotationDeclaration(Annotation.key_str, null); + keyann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); AnnotationDeclaration mustundann = createAnnotationDeclaration("must_understand", null); - mustundann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + mustundann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); createAnnotationDeclaration("default_literal", null); @@ -219,25 +219,25 @@ public Context( //String.valueOf(Integer.MAX_VALUE))); AnnotationDeclaration unitsann = createAnnotationDeclaration("units", null); - unitsann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_STRING), "")); + unitsann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_STRING), "")); AnnotationDeclaration defaultann = createAnnotationDeclaration("default", null); - defaultann.addMember(new AnnotationMember("value", new AnyTypeCode(), null)); + defaultann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); AnnotationDeclaration minann = createAnnotationDeclaration("min", null); - minann.addMember(new AnnotationMember("value", new AnyTypeCode(), null)); + minann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); AnnotationDeclaration maxann = createAnnotationDeclaration("max", null); - maxann.addMember(new AnnotationMember("value", new AnyTypeCode(), null)); + maxann.addMember(new AnnotationMember(Annotation.value_str, new AnyTypeCode(), null)); AnnotationDeclaration bit_boundann = createAnnotationDeclaration("bit_bound", null); - bit_boundann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_USHORT), "-1")); + bit_boundann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_USHORT), "-1")); AnnotationDeclaration externalann = createAnnotationDeclaration("external", null); - externalann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + externalann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); AnnotationDeclaration nestedann = createAnnotationDeclaration("nested", null); - nestedann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + 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"); @@ -257,17 +257,17 @@ public Context( // CORBA, DDS, * (any), or custom value AnnotationDeclaration onewayann = createAnnotationDeclaration("oneway", null); - onewayann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + onewayann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); AnnotationDeclaration amiann = createAnnotationDeclaration("ami", null); - amiann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + amiann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); AnnotationDeclaration hashid_annotation = createAnnotationDeclaration(Annotation.hashid_str, null); - hashid_annotation.addMember(new AnnotationMember("value", new StringTypeCode(Kind.KIND_STRING, null, null), "")); + hashid_annotation.addMember(new AnnotationMember(Annotation.value_str, new StringTypeCode(Kind.KIND_STRING, null, null), "")); // Create default @non_serialized annotation. AnnotationDeclaration non_serializedann = createAnnotationDeclaration("non_serialized", null); - non_serializedann.addMember(new AnnotationMember("value", new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); + non_serializedann.addMember(new AnnotationMember(Annotation.value_str, new PrimitiveTypeCode(Kind.KIND_BOOLEAN), "true")); } 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 f88a12ae..2a0fa3a4 100644 --- a/src/main/java/com/eprosima/idl/parser/tree/Annotation.java +++ b/src/main/java/com/eprosima/idl/parser/tree/Annotation.java @@ -42,6 +42,8 @@ public class Annotation public static final String ex_mutable_str = "MUTABLE"; public static final String ex_mutable_val = "2"; + public static final String value_str = "value"; + public Annotation(AnnotationDeclaration declaration) { m_declaration = declaration; 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 7f365a7f..006d071c 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/MemberedTypeCode.java @@ -122,7 +122,7 @@ public boolean addMember( if (member.isAnnotationKey() && Kind.KIND_STRUCT != getKind()) { throw new ParseException(null, "Error in member " + member.getName() + - ": @" + Annotation.key_str + " annotations only supported for structure's members."); + ": @" + Annotation.key_str + " annotations only supported for structure's members (Union discriminator still pending implementation)."); } if (null != member.getAnnotationBitBound() && ( Kind.KIND_ENUM != getKind() && Kind.KIND_BITMASK != getKind())) @@ -192,7 +192,7 @@ public boolean addMember( /*! * This function calculates the MemberId for the given member. - * Derived classes can use this function but it must be called from a override addMember(). + * Derived classes can use this function but it must be called from an override addMember(). */ protected void calculate_member_id_( Member member) @@ -241,7 +241,7 @@ else if (!isAnnotationAutoid() || getAnnotationAutoidValue().equals(Annotation.a } /*! - * This function check there is no other member with same id. + * This function checks there is no other member with same id. */ protected boolean check_unique_member_id( Member member)