Version 7.1.7

Patch release: OCL parser fixes + IMG2UML merge-into-existing-model. Closes #198, #202, and #338. No metamodel or public API changes — the OCL work is a grammar fix plus a diagnostics layer, and the IMG2UML change adds an optional parameter while preserving the original behaviour when the active diagram is empty.

Highlights

  • OCL accepts attributes named ``size`` (closes #198): size is a reserved lexer keyword for the OCL ->size() / .size() collection operation, so any domain model with an attribute literally named size failed to parse with mismatched input '>' expecting '(' — the lexer tokenized the attribute name as SIZE and the parser insisted on LPAREN RPAREN after it. The reporter blamed inheritance because their repro had size on a parent class, but the bug fired identically on a direct attribute. Grammar fix: expression DOT SIZE #dotSizeNavigation added as a fallback rule below the existing DOT SIZE LPAREN RPAREN. ANTLR’s longest-match keeps .size() winning when parens follow, so collection->size() and string.size() still parse unchanged. The visitor gains visitDotSizeNavigation that resolves size via the same property-lookup path as visitDotNavigation. Seven regression tests in tests/BUML/metamodel/ocl/test_size_attribute.py.

  • OCL parser emits actionable error messages (closes #202): the raw ANTLR diagnostics (mismatched input 'then' expecting <EOF>, missing ')' at '<EOF>') exposed internal parser state and used token names that mean little to someone writing an OCL constraint. The worst example from the issue — forgetting the if before then ... else ... — surfaced as Error: pop from empty list, which gives zero hint about what went wrong. besser/BUML/notations/ocl/error_handling.py now sits on top of ANTLR’s error listener and rewrites diagnostics into OCL-level hints: Did you forget the 'if'?, Missing 'endif', Missing closing ')', operand on the right is missing, must start with 'context <ClassName> inv: ...', and so on. When no targeted pattern matches, the raw ANTLR message is kept as a fallback but reformatted into a consistent line N, column M: <msg> shape. Thirteen regression tests in tests/BUML/metamodel/ocl/test_error_messages.py pin every rewrite rule plus positive-parse sanity checks so the translation layer doesn’t reject valid OCL.

  • IMG2UML extends an existing class diagram instead of replacing it (closes #338): when an image is uploaded while the active ClassDiagram already has elements, the image is now merged into the current model — same-name classes are preserved and only new attributes/methods/relationships from the image are appended, new classes are added with their own relationships. image_to_buml and image_to_plantuml gain an optional existing_model parameter; when supplied, a compact textual summary of the current classes, attributes, methods, associations and inheritance is included in the vision prompt with explicit merge rules so the LLM returns a single merged PlantUML chunk. /get-json-model-from-image carries an optional existing_model form field with the current diagram JSON, converted via process_class_diagram and forwarded down. The frontend submodule only sends the active ClassDiagram when it is non-empty, so empty-diagram imports keep the original “replace” behaviour.

Testing

Twenty new OCL tests (seven for the size keyword fix, thirteen for the error-message rewrites) cover every targeted pattern plus positive-parse guards. Full suite: 712 passed, 5 skipped, 3 xfailed — no regressions against v7.1.6.