Annotate Everything! Properties on the Structural Model
If you look at Pharo, the structure of the whole system is expressed in terms of Objects: Classes and Methods are objects, as they are in ST80.
But in addition, we model packages, defined Variables (yes, every defined instance variable has a meta object!) and even the structure of methods (the AST).
All of them support an API to set and query properties:
propertyAt: propName
propertyAt: propName ifAbsent: aBlock
propertyAt: propName put: propValue
hasProperty: propName
removeProperty: propName
removeProperty: propName ifAbsent: aBlock
These are implemented on:
- Variable: any Variable defined in the system (including e.g. “Object”, the global pointing to the class Object)
- CompiledMethod: Methods, like OrderedCollection>>#do:
- RBProgramNode: all AST nodes
- RPackage: Packages
- Behavior: Classes and Traits
What is this useful for? For one, properties can be used in the same way as instance variables, with the difference that they are not defined by the class definition. Just add accessors and then use them as if you would use an instance Varianle with accessors.
This is interesting for one as a first step: adding a new ivar to a system class is some cases just not possible (e.g. CompiledMethod), in all cases using a property is often exactly what you need if you are starting with an implementation, even though finally it might be better turned into an instance variable. It, too, simplifies adding state to system classes from your package using extensions (very useful for experimental code).
Another use-case is meta data: properties are per object state. They allow you to easily annoate code with data (without the annotations being textual in the source).
How do we use properties now? We have a number of examples:
When a class is removed, it’s name is changed ot “AnObsoleteOriginalName”. In the past, the test if a class is obsolete or not did check if the class starts with this substring. We changed it to instead check a property.
MetaLinks are non-textual annotations on the AST that attach meta-objects to operations to modify them. MetaLinks are stored as properties.
PharoDoc is a system that allows us to add specially formatted comments that are runnable examples for methods. To not have to re-parse these, we add them as properties to the Comment node of the AST the first time someone needs them. This speeds up e.g. Syntax hightlighting (or any other user of DocComments)
FFI (the subsystem to call C functions), tags compiled methods with #isFFIMethod.
Note: all the properties are not persisted with the textual representation, even though they are attached to objects that represent code. This means it is the duty of the client to make sure that they get re-applied in case the structure is re-created from the textual representation. This is especially important for the AST: it is created only on demand and flushed on image save, client have to use properties with this in mind.
Posted on November 24, 2020 #Pharo