Skip to content

Releases: pharo-ide/ClassAnnotation

Sources converted to tonel format

19 Sep 12:38
eb3a487
Compare
Choose a tag to compare
Merge pull request #28 from pharo-ide/migrate-sources-to-tonel

migrate-sources-to-tonel

Registry updating is improved

05 Mar 16:48
d2c512f
Compare
Choose a tag to compare

Commenting classAnnotation pragma now removes annotation from class

Redefined annotations

02 Mar 13:56
22c67fd
Compare
Choose a tag to compare

Now there is special mechanizm to redefine all collected annotations. When cache is updated all redefined annotations are restored.

Read details in readme section "Redefined annotations"

Also in this versions the message to reset cache was renamed from #resetAll to #resetCache

ClassAnnotationRegistry and CompositeAnnotationContext

12 Feb 09:39
1f2a7fa
Compare
Choose a tag to compare
  • ClassAnnotationRegistry is extracted
    Now annotation cache is reified as default registry instance. It is not managed in class variable of ClassAnnotation.

  • The annotation registry do not depends on PragmaCollector
    PragmaCollector update logic was not enough for updating inherited class annotations in the cache.

  • classAnnotationDependency pragma is added.
    It force update of annotation cache (registry) when dependency methods are modified (dependancy methods are sent inside annotation definition methods).

  • fix class change handling logic #22
    Registry is updated when change happens with class which have or will have inherited annotations from superclasses

  • CompositeAnnotationContext is added
    Now contexts can be concatenated by comma message. They all should be satisfied to activate annotation.

It is stable major version 0.2

11 Dec 16:56
1f2a7fa
Compare
Choose a tag to compare

Contextual annotations

Now annotations can be defined with context where they can be used.
Imaging that you want annotate command classes with shortcuts for specific widgets:

MyCommand class>>widget1ShortcutAnnotation
   <classAnnotation>
   ShortcutAnnotation using: $r meta for: MyWidgetClass1

MyCommand class>> widget2ShortcutAnnotation
   <classAnnotation>
   ShortcutAnnotation using: $t meta for: MyWidgetClass2

Then you can query all shortcuts which should be active for concrete widget:

ShortcutAnnotation activeAnnotationsInContext: aMyWidgetInstance

Declaring context using classes is simplest case. Underhood class is converted to AnnotationContext instance using #asAnnotationContext message. Then during annotations lookup it simply asks #isKindOf: for given context instances.
For advanced scenarios you can implement more complex annotation context and define specific DSL to use them for annotations and queries.

Any annotation class can redefine meaning of active annotation with extra conditions. For example it can delegate decision to annotated class itself:

ShortcutAnnotation >>isActiveInContext: aMyWidgetInstance
	^(super isActiveInContext: aMyWidgetInstance)
			and: [annotatedClass canBeUsedInWidget: aMyWidgetInstance]

But for some scenarios you may need to query annotations according to original "active" definition despite of extra conditions. For such cases the "visibility" of annotation is introduced: the annotation is visible if it is declared for given context:

ClassAnnotation>>isVisibleInContext: aContext
	^activeContext describes: aContext

So the visible annotation is not necessary active. But active annotation is always visible in given context:

ClassAnnotation>>isActiveInContext: aContext
	^self isVisibleInContext: aContext

Imaging that you want annotate commands with context menu information (where they should be accessible). In that case disabled menu items can represent commands which are visible for application but not active in given context (because selected items is not appropriate for them).

To query visible annotations where are few methods:

ContextMenuAnnotation visibleInstancesInContext: anUserContext
ContextMenuAnnotation visibleInstancesInContext: anUserContext do: aBlock

Annotation priority

For particular scenarios it can be important to define order in which annotations are processed.
For context menu example this order can be used to sort menu items.
For shortcut example it allows override existing shortcuts of application.

So concept of annotation priority was introduced for this reason. Any annotation can define it. Annotation with greater priority value is processed first by enumeration methods:

  • registeredInstancesDo:
  • activeInstancesInContext:do:
  • visibleInstancesInContext:do:

Priority is holden as instance variable. So you can specify it in declaration method:

MyCommand class>>shortcutAnnotation
   <classAnnotation>
   (ShortcutAnnotation using: $r meta for: MyWidgetClass) 
       priority: 1000

Of course for your annotation you can add methods which are suitable for your domain.

In some cases you would need override order in which annotations should be sorted. For example, you can say that command with greater priority should be at the end of menu.
For such cases you can override class side method #createContainerForRegistry:

MySpecificAnnotation class>>createContainerForRegistry
     ^SortedCollection sortBlock: #priority ascending

Forbidden annotation

Annotation can forbid annotating of particular classes. For example it can forbid abstract classes.

MySpecificAnnotation>>isForbidden
      ^annotatedClass isAbstract

Such annotations will not be added to the registry and forbidden classes will not include them

Better understanding of contextual annotations

21 Dec 16:44
2de1e47
Compare
Choose a tag to compare

Now it is clear that annotation context describes users of annotation.
And activeContext of annotation restricts its possible set of users.

So argument of query messages is renamed to the anAnnotationUser.
And other changes according to this idea.
So it is cosmetic changes. But it is important for understanding the model of contextual annotations

Annotations with context and priority

11 Dec 16:37
5c6a1f5
Compare
Choose a tag to compare

Contextual annotations

Now annotations can be defined with context where they can be used.
Imaging that you want annotate command classes with shortcuts for specific widgets:

MyCommand class>>widget1ShortcutAnnotation
   <classAnnotation>
   ShortcutAnnotation using: $r meta for: MyWidgetClass1

MyCommand class>> widget2ShortcutAnnotation
   <classAnnotation>
   ShortcutAnnotation using: $t meta for: MyWidgetClass2

Then you can query all shortcuts which should be active for concrete widget:

ShortcutAnnotation activeAnnotationsInContext: aMyWidgetInstance

Declaring context using classes is simplest case. Underhood class is converted to AnnotationContext instance using #asAnnotationContext message. Then during annotations lookup it simply asks #isKindOf: for given context instances.
For advanced scenarios you can implement more complex annotation context and define specific DSL to use them for annotations and queries.

Any annotation class can redefine meaning of active annotation with extra conditions. For example it can delegate decision to annotated class itself:

ShortcutAnnotation >>isActiveInContext: aMyWidgetInstance
	^(super isActiveInContext: aMyWidgetInstance)
			and: [annotatedClass canBeUsedInWidget: aMyWidgetInstance]

But for some scenarios you may need to query annotations according to original "active" definition despite of extra conditions. For such cases the "visibility" of annotation is introduced: the annotation is visible if it is declared for given context:

ClassAnnotation>>isVisibleInContext: aContext
	^activeContext describes: aContext

So the visible annotation is not necessary active. But active annotation is always visible in given context:

ClassAnnotation>>isActiveInContext: aContext
	^self isVisibleInContext: aContext

Imaging that you want annotate commands with context menu information (where they should be accessible). In that case disabled menu items can represent commands which are visible for application but not active in given context (because selected items is not appropriate for them).

To query visible annotations where are few methods:

ContextMenuAnnotation visibleInstancesInContext: anUserContext
ContextMenuAnnotation visibleInstancesInContext: anUserContext do: aBlock

Annotation priority

For particular scenarios it can be important to define order in which annotations are processed.
For context menu example this order can be used to sort menu items.
For shortcut example it allows override existing shortcuts of application.

So concept of annotation priority was introduced for this reason. Any annotation can define it. Annotation with greater priority value is processed first by enumeration methods:

  • registeredInstancesDo:
  • activeInstancesInContext:do:
  • visibleInstancesInContext:do:

Priority is holden as instance variable. So you can specify it in declaration method:

MyCommand class>>shortcutAnnotation
   <classAnnotation>
   (ShortcutAnnotation using: $r meta for: MyWidgetClass) 
       priority: 1000

Of course for your annotation you can add methods which are suitable for your domain.

In some cases you would need override order in which annotations should be sorted. For example, you can say that command with greater priority should be at the end of menu.
For such cases you can override class side method #createContainerForRegistry:

MySpecificAnnotation class>>createContainerForRegistry
     ^SortedCollection sortBlock: #priority ascending

Forbidden annotation

Annotation can forbid annotating of particular classes. For example it can forbid abstract classes.

MySpecificAnnotation>>isForbidden
      ^annotatedClass isAbstract

Such annotations will not be added to the registry and forbidden classes will not include them

it is the stable version 0.1

02 Oct 09:22
Compare
Choose a tag to compare
Readme fix

classAnnotation instead of metaAnnotation

First version is stabilised names and API

02 Oct 09:22
Compare
Choose a tag to compare
Readme fix

classAnnotation instead of metaAnnotation