Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix find and set default value for unions [20587] #124

Merged
merged 4 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,7 @@ union_type [Vector<Annotation> annotations, ArrayList<Definition> defs] returns
LEFT_BRACE switch_body[unionTP] RIGHT_BRACE
{
// Calculate default label.
TemplateUtil.setUnionDefaultLabel(defs, unionTP, ctx.getScopeFile(), line);
TemplateUtil.find_and_set_default_discriminator_value(defs, unionTP);

if(ctx.isInScopedFile() || ctx.isScopeLimitToAll())
{
Expand Down Expand Up @@ -1862,7 +1862,7 @@ case_stmt [UnionTypeCode unionTP] returns [TemplateGroup tg = null]
}
: ( KW_CASE const_exp
{
labels.add(TemplateUtil.checkUnionLabel(unionTP.getDiscriminator().getTypecode(), $const_exp.literalStr, ctx.getScopeFile(), _input.LT(1) != null ? _input.LT(1).getLine() - ctx.getCurrentIncludeLine() : 1));
labels.add(TemplateUtil.checkUnionLabel(unionTP.getDiscriminator().getTypecode(), $const_exp.literalStr));
} COLON
| KW_DEFAULT { defaul = true; } COLON
)+
Expand Down
114 changes: 72 additions & 42 deletions src/main/java/com/eprosima/idl/generator/manager/TemplateUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,38 @@ else if(type.startsWith("std::vector"))
return type;
}

public static void setUnionDefaultLabel(ArrayList<Definition> defs, UnionTypeCode union_type, String scopeFile, int line)
/*!
* This function tries to find a default discriminator value for the union following the guidelines extracted from
* the standard.
*
adriancampo marked this conversation as resolved.
Show resolved Hide resolved
* \b 6.14.2 Mapping for Union Types \b
* "If there is a default case specified, the union is initialized to this default case.
* In case the union has an implicit default member it is initialized to that case.
* In all other cases it is initialized to the first discriminant value specified in IDL"
*/
public static void find_and_set_default_discriminator_value(ArrayList<Definition> defs, UnionTypeCode union_type)
{
TypeCode dist_type = union_type.getDiscriminator().getTypecode();
List<Member> members = union_type.getMembers();
TypeCode disc_type = union_type.getDiscriminator().getTypecode();

if(dist_type != null && union_type.getDefaultMember() != null)
if (Kind.KIND_ALIAS == disc_type.getKind())
{
if(dist_type.getKind() == Kind.KIND_OCTET ||
dist_type.getKind() == Kind.KIND_INT8 ||
dist_type.getKind() == Kind.KIND_SHORT ||
dist_type.getKind() == Kind.KIND_LONG ||
dist_type.getKind() == Kind.KIND_LONGLONG ||
dist_type.getKind() == Kind.KIND_UINT8 ||
dist_type.getKind() == Kind.KIND_USHORT ||
dist_type.getKind() == Kind.KIND_ULONG ||
dist_type.getKind() == Kind.KIND_ULONGLONG ||
dist_type.getKind() == Kind.KIND_CHAR ||
dist_type.getKind() == Kind.KIND_WCHAR)
disc_type = ((AliasTypeCode)disc_type).getContentTypeCode();
}

if(disc_type != null)
{
if(disc_type.getKind() == Kind.KIND_OCTET ||
disc_type.getKind() == Kind.KIND_INT8 ||
disc_type.getKind() == Kind.KIND_SHORT ||
disc_type.getKind() == Kind.KIND_LONG ||
disc_type.getKind() == Kind.KIND_LONGLONG ||
disc_type.getKind() == Kind.KIND_UINT8 ||
disc_type.getKind() == Kind.KIND_USHORT ||
disc_type.getKind() == Kind.KIND_ULONG ||
disc_type.getKind() == Kind.KIND_ULONGLONG ||
disc_type.getKind() == Kind.KIND_CHAR ||
disc_type.getKind() == Kind.KIND_WCHAR)
{
long dvalue = -1;
boolean found = true;
Expand All @@ -79,15 +93,17 @@ public static void setUnionDefaultLabel(ArrayList<Definition> defs, UnionTypeCod
catch(NumberFormatException nfe)
{
// It could be a const
for (Definition def : defs)
if (null != defs)
{
if (def.isIsConstDeclaration())
for (Definition def : defs)
{
ConstDeclaration decl = (ConstDeclaration)def;
if (decl.getName().equals(label))
if (def.isIsConstDeclaration())
{
value = Long.decode(decl.getValue());
//System.out.println("Label " + label + " has value " + value);
ConstDeclaration decl = (ConstDeclaration)def;
if (decl.getName().equals(label))
{
value = Long.decode(decl.getValue());
}
}
}
}
Expand All @@ -109,9 +125,9 @@ public static void setUnionDefaultLabel(ArrayList<Definition> defs, UnionTypeCod
union_type.setDefaultvalue(Long.toString(dvalue));
union_type.setJavaDefaultvalue(Long.toString(dvalue));
}
else if(dist_type.getKind() == Kind.KIND_BOOLEAN)
else if(disc_type.getKind() == Kind.KIND_BOOLEAN)
{
if(members.size() == 1 && ((UnionMember)members.get(0)).getLabels().size() == 1)
if(1 == members.size() && 1 == ((UnionMember)members.get(0)).getLabels().size())
{
if(((UnionMember)members.get(0)).getLabels().get(0).equals("true"))
{
Expand All @@ -125,23 +141,24 @@ else if(((UnionMember)members.get(0)).getLabels().get(0).equals("false"))
}
else
{
//TODO
//throw new ParseException(((UnionMember)members.get(0)).getLabels().get(0), "is not a valid label for a boolean discriminator.");
throw new ParseException(null, "is not a valid label for a boolean discriminator.");
}
}
else
else if(2 == members.size() && 1 == ((UnionMember)members.get(0)).getLabels().size() &&
1 == ((UnionMember)members.get(1)).getLabels().size())
{
if(members.size() > 2)
throw new ParseException(null, "boolean switch cannot have more than two elements.");

union_type.setDefaultvalue("false");
union_type.setJavaDefaultvalue("false");
union_type.setDefaultvalue(((UnionMember)members.get(0)).getLabels().get(0));
union_type.setJavaDefaultvalue(((UnionMember)members.get(0)).getLabels().get(0));
}
else
{
throw new ParseException(null, "boolean switch is malformed.");
}
}
else if(dist_type.getKind() == Kind.KIND_ENUM)
else if(disc_type.getKind() == Kind.KIND_ENUM)
{
EnumTypeCode enume = (EnumTypeCode)dist_type;
EnumTypeCode enume = (EnumTypeCode)disc_type;
List<Member> list = new ArrayList<Member>(members);
List<Member> enum_members = new ArrayList<Member>();
enum_members.addAll(enume.getMembers());
Expand Down Expand Up @@ -170,8 +187,11 @@ else if(dist_type.getKind() == Kind.KIND_ENUM)
union_type.setDefaultvalue(enume.getScopedname() + "::" + enum_members.get(0).getName());
union_type.setJavaDefaultvalue(enume.javapackage + enume.getJavaScopedname() + "." + enum_members.get(0).getName());
}
else
throw new ParseException(null, "All enumeration elements are used in the union");
else if (0 < members.size() && 0 < ((UnionMember)members.get(0)).getLabels().size())
{
union_type.setDefaultvalue(((UnionMember)members.get(0)).getLabels().get(0));
union_type.setJavaDefaultvalue(((UnionMember)members.get(0)).getLabels().get(0));
}
}
else
{
Expand All @@ -180,23 +200,20 @@ else if(dist_type.getKind() == Kind.KIND_ENUM)
}
}

public static String checkUnionLabel(TypeCode dist_type, String label, String scopeFile, int line)
public static String checkUnionLabel(TypeCode disc_type, String label)
{
// TODO Faltan tipos: short, unsigneds...
if(dist_type != null)
if(disc_type != null)
{
if(dist_type.getKind() == Kind.KIND_ENUM)
if(disc_type.getKind() == Kind.KIND_ENUM)
{
EnumTypeCode enume = (EnumTypeCode)dist_type;
EnumTypeCode enume = (EnumTypeCode)disc_type;

if(enume.getScope() != null)
{
if(label.contains("::"))
{
if(!label.startsWith(enume.getScope()))
{
//TODO
//throw new ParseException(label, "was not declared previously");
throw new ParseException(null, "was not declared previously");
}
else
Expand All @@ -209,11 +226,24 @@ public static String checkUnionLabel(TypeCode dist_type, String label, String sc
{
if(label.contains("::"))
{
//TODO
//throw new ParseException(label, "was not declared previously");
throw new ParseException(null, "was not declared previously");
}
}

boolean found = false;
for(Member member : enume.getMembers())
{
if (label.equals(member.getName()))
{
found = true;
break;
}
}

if (!found)
{
throw new ParseException(null, "Invalid enumerator label");
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ public boolean isDefault()
return m_default;
}

public boolean isPrintable()
{
return m_default || (null != m_labels && 0 < m_labels.size());
}

private List<String> m_internallabels = null;
private List<String> m_labels = null;
private List<String> m_javalabels = null;
Expand Down
27 changes: 0 additions & 27 deletions src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,33 +233,6 @@ public boolean isIsPlain()
return false;
}

// Add member and the default one at the end.
public List<Member> getMembersDefaultAtEnd()
{
int position = 0;
List<Member> ret_members = new ArrayList<Member>();
Member default_member = null;

for (Member m : getMembers())
{
if (position == m_defaultindex)
{
default_member = m;
}
else
{
ret_members.add(m);
}
}

if (null != default_member)
{
ret_members.add(default_member);
}

return ret_members;
}

@Override
public void addAnnotation(
Context ctx,
Expand Down