enhancement
major
defect
major
minor
major
#29745
Zugriff auf ein abstraktes Attribut meldet einen Fehler, der nicht sagt, dass das Attribut abstrakt ist: eigene Storage für abstrakte Attribute
Problem
Abstrakte Attribute bekommen die Storage NoStorage. Ein Wertzugriff auf ein abstraktes Attribut meldet deshalb denselben Fehler wie ein Attribut, dessen Speicherimplementierung nicht instanziiert werden konnte ("Entweder ist es als abstrakt deklariert, oder seine Speicherimplementierung konnte nicht instanziiert werden"). Der Meldung ist nicht zu entnehmen, dass das Attribut abstrakt ist und deshalb keine eigenen Werte hat.
Lösung
- Abstrakte Attribute bekommen eine eigene Storage AbstractAttributeStorage. Wie bei NoStorage schlägt jeder Wertzugriff fehl, jetzt aber mit einer eigenen Meldung, die den Zugriff auf ein abstraktes Attribut benennt: Ein abstraktes Attribut hat keine eigenen Werte, Werte haben nur die Attribute, die es in konkreten Typen überschreiben.
- isReadOnly() der neuen Storage liefert wie bei NoStorage true. Damit bleibt TLStructuredTypePart#isDerived() für abstrakte Attribute unverändert true, Aufrufer müssen nicht angepasst werden.
- NoStorage bleibt für Attribute, deren Speicherimplementierung nicht instanziiert werden kann.
Betroffen ist com.top_logic.element.
Verworfen
Ursprünglich sollte isReadOnly() für abstrakte Attribute fehlschlagen, damit isDerived() abstrakte und berechnete Attribute unterscheidet und jeder Aufrufer abstrakte Attribute explizit behandelt (PR pull:1795). Eine konkrete Klasse kann aber ein geerbtes abstraktes Attribut legitim nicht überschreiben (z.B. tl.element:StructuredElement#parent an Wurzeltypen wie OrgRoot). Damit hätten alle Stellen angepasst werden müssen, die über alle Attribute eines Typs iterieren (Defaultwerte, Constraint-Checks, Kopieren, Export, Changelog, Formulare, ...). Das ist zu aufwändig; der Ansatz wurde verworfen.