Skip to content
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
18 changes: 17 additions & 1 deletion WDL/Tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,30 @@ class StructTypeDef(SourceNode):
there. The referenced definition might itself be imported from yet another document.
"""

parameter_meta: Dict[str, Any]
""":type: Dict[str,Any]

``parameter_meta{}`` section as a JSON-like dict"""

meta: Dict[str, Any]
""":type: Dict[str,Any]

``meta{}`` section as a JSON-like dict"""

def __init__(
self,
pos: SourcePosition,
name: str,
members: Dict[str, Type.Base],
parameter_meta: Dict[str, Any],
meta: Dict[str, Any],
imported: "Optional[Tuple[Document,StructTypeDef]]" = None,
) -> None:
super().__init__(pos)
self.name = name
self.members = members
self.parameter_meta = parameter_meta
self.meta = meta
self.imported = imported

@property
Expand Down Expand Up @@ -1963,7 +1977,9 @@ def _import_structs(doc: Document):
except KeyError:
pass
if not existing:
st2 = StructTypeDef(imp.pos, name, st.members, imported=(imp.doc, st))
st2 = StructTypeDef(
imp.pos, name, st.members, st.parameter_meta, st.meta, imported=(imp.doc, st)
)
doc.struct_typedefs = doc.struct_typedefs.bind(name, st2)


Expand Down
2 changes: 1 addition & 1 deletion WDL/_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
bound_decl: type CNAME "=" expr -> decl
?any_decl: unbound_decl | bound_decl

struct: "struct" CNAME "{" unbound_decl* "}"
struct: "struct" CNAME "{" (unbound_decl | meta_section)* "}"

///////////////////////////////////////////////////////////////////////////////////////////////////
// type
Expand Down
34 changes: 26 additions & 8 deletions WDL/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,14 +586,32 @@ def struct(self, meta, items):
name = items[0]
self._check_keyword(self._sp(meta), name)
members = {}
for d in items[1:]:
assert not d.expr
if d.name in members:
raise Error.MultipleDefinitions(
self._sp(meta), f"duplicate struct member '{d.name}'"
)
members[d.name] = d.type
return Tree.StructTypeDef(self._sp(meta), name, members)
parameter_meta = None
meta_section = None
for item in items[1:]:
if isinstance(item, dict):
if "meta" in item:
if meta_section is not None:
raise Error.MultipleDefinitions(
self._sp(meta), "redundant struct meta sections"
)
meta_section = item["meta"]
elif "parameter_meta" in item:
if parameter_meta is not None:
raise Error.MultipleDefinitions(
self._sp(meta), "redundant struct parameter_meta sections"
)
parameter_meta = item["parameter_meta"]
else:
assert False
elif isinstance(item, Tree.Decl):
assert not item.expr
if item.name in members:
raise Error.MultipleDefinitions(
self._sp(meta), f"duplicate struct member '{item.name}'"
)
members[item.name] = item.type
return Tree.StructTypeDef(self._sp(meta), name, members, parameter_meta, meta_section)

def import_alias(self, meta, items):
assert len(items) == 2
Expand Down
3 changes: 1 addition & 2 deletions tests/spec_tests/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,9 @@ wdl-1.2:
- chunk_array.wdl
- file_sizes_task.wdl
- multi_nested_inputs.wdl
- import_structs.wdl
- input_hint_task.wdl
- join_paths_task.wdl
- one_mount_point_task.wdl
- person_struct_task.wdl
- string_to_file.wdl
- test_allow_nested_inputs.wdl
- test_contains.wdl
Expand All @@ -58,6 +56,7 @@ wdl-1.2:
- map_to_struct.wdl # issue #712
- multiline_string_placeholders.wdl # wrong namespace in expected output
- nested_scatter.wdl # expected output is wrong
- person_struct_task.wdl # erroneous use of bash -gt to compare Float and Int
- placeholders.wdl # wrong namespace in expected output
- placeholder_none.wdl # questionable claim that interpolations should swallow errors
- primitive_literals.wdl # expected output is wrong
Expand Down
63 changes: 63 additions & 0 deletions tests/test_1doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,69 @@ def test_parser(self):
with self.assertRaises(WDL.Error.MultipleDefinitions):
doc = WDL.parse_document(doc)

def test_meta(self):
doc = r"""
version 1.2

struct Person {
meta {
description: "Something"
more_stuff: "Also here"
coolness: 7
}
String name
parameter_meta {
name: "A name"
age: "An age"
}
Int age
}
"""
doc = WDL.parse_document(doc)
doc.typecheck()
struct = doc.struct_typedefs.resolve("Person")
self.assertEqual(struct.meta["description"], "Something")
self.assertEqual(struct.meta["more_stuff"], "Also here")
self.assertEqual(struct.meta["coolness"].value, 7)
self.assertEqual(struct.parameter_meta["name"], "A name")
self.assertEqual(struct.parameter_meta["age"], "An age")

doc = r"""
version 1.2

struct Person {
meta {
description: "Something"
}
String name
meta {
description2: "Something else"
}
Int age
}
"""
with self.assertRaises(WDL.Error.MultipleDefinitions):
doc = WDL.parse_document(doc)

doc = r"""
version 1.2

struct Person {
parameter_meta {
name: "A name"
age: "An age"
}
String name
Int age
parameter_meta {
name: "A name"
age: "An age"
}
}
"""
with self.assertRaises(WDL.Error.MultipleDefinitions):
doc = WDL.parse_document(doc)

def test_decl(self):
doc = r"""
version 1.0
Expand Down
Loading