Support block comments in selector filter syntax (#5023)

The filter_elements selector grammar had no way to comment out part of a
query, so users had to delete and retype text to temporarily toggle a
facet. Add a /* ... */ block comment terminal that is ignored by the
lexer, and tolerate a trailing "+" so that commenting out the final
operand (e.g. "IfcWall + /* IfcSlab */") parses cleanly. Comments may
span multiple lines; a /* sequence inside a quoted string is not treated
as a comment. Only the filter grammar is affected, not get_element or
format which use "/" for regex and division.

Adds a regression test and documents the syntax.

Generated with the assistance of an AI coding tool.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Petru Conduraru
2026-07-12 07:45:21 +03:00
committed by Dion Moult
parent 0b7e25a3ef
commit 5c11946470
3 changed files with 24 additions and 1 deletions
@@ -351,6 +351,22 @@ class TestFilterElements(test.bootstrap.IFC4):
assert subject.filter_elements(self.file, "IfcWall, Name=Foo + IfcSlab") == {element, element2}
assert subject.filter_elements(self.file, "IfcWall, Name=Foo + IfcSlab, Name=Bar") == {element, element2}
def test_block_comments_are_ignored(self):
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
element.Name = "Foo"
element2 = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcSlab")
element2.Name = "Bar"
# A /* ... */ block comment lets a query be toggled off without deleting the text.
assert subject.filter_elements(self.file, "IfcWall /* + IfcSlab */") == {element}
assert subject.filter_elements(self.file, "IfcWall + /* IfcSlab */") == {element}
assert subject.filter_elements(self.file, "/* IfcWall + */ IfcSlab") == {element2}
assert subject.filter_elements(self.file, "IfcWall /* commented */ + IfcSlab") == {element, element2}
# Comments may span multiple lines.
assert subject.filter_elements(self.file, "IfcWall + /* multi\nline\ncomment */ IfcSlab") == {element, element2}
# A /* sequence inside a quoted string is not treated as a comment.
element.Name = "a/*b"
assert subject.filter_elements(self.file, 'IfcWall, Name="a/*b"') == {element}
def test_using_elements_argument(self):
wall = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcWall")
slab = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcSlab")