Romain Rouvoy
email: romain.rouvoy@inria.fr

Nicolas Pessemier
email: nicolas.pessemier@inria.fr

Renaud Pawlak
email: renaud.pawlak@inria.fr

Philippe Merle
email: philippe.merle@inria.fr

Philippe Merle Jacquard

Using Attribute-Oriented Programming to Leverage Fractal-Based Developments

HAL is

Introduction

Component-Based Software Engineering (CBSE) is concerned with the development of highly reusable business components which declare contractually specified interfaces to communicate with each other. CBSE facilitates the development of high quality applications with shorter development cycles and reduces coding effort. However, in practice, it appears that the component developer's task is not only devoted to the design and implementation of the business logic of the applications but also to the integration of redundant and error prone technical properties.

A convenient way to address this issue is to use Attribute-Oriented Programming (@OP) techniques. @OP proposes to mark program code with metadata to clearly separate the business logic from a domain-specific logic (typically technical properties). @OP is gaining popularity with the recent introduction of annotations in Java 2 standard edition (J2SE) 5.0 [START_REF] Gosling | The Java Language Specification, Third Edition. Addison-Westley Professional Computing[END_REF] or in XDoclet [START_REF] Walls | XDoclet in Action[END_REF], and attributes in C# [START_REF]C# Language Specification[END_REF]. Recently, the Enterprise Java Bean (EJB) 3.0 specification extensively uses annotations to make EJB programming easier [START_REF] Demichiel | Enterprise JavaBeans (EJB) Specification[END_REF]. The Service Component Architecture (SCA) component implementation model provides a series of annotations which can be placed in the code to mark significant elements of the implementation which are used by the SCA runtime [START_REF][END_REF].

The contribution of this paper is to present Fraclet, an annotationbased framework using @OP to leverage the Fractal component developer's task. Fraclet provides a set of dedicated annotations to mark the Fractal-related technical properties in the program code. To achieve this goal, Fraclet introduces a seamless design process for Fractal component developers. Thanks to @OP, most of the component artifacts are automatically generated.

[copyright notice will appear here]

Fraclet is developed to deal with the Java implementations of the Fractal component model. We have experimented two different, but functionally equivalent, implementations of the Fraclet annotation framework. The first one uses XDoclet and Velocity to define the code generators and to produce the various artifacts required by the Fractal component model. The second one uses Spoon [START_REF] Pawlak | Spoon : Annotation-Driven Program Transformation -The AOP Case[END_REF], a Java 5-compatible processing tool, which supports the processing of Java 5 annotations. The Fraclet developer can then take advantage of Java 5 type safety and annotations. Regardless of the implementations, we show that, using Fraclet, about 50% of the handwritten program code can be saved without loosing the semantics of the application, while the rest of the program code is automatically generated and continuously integrated.

The remainder of this paper is organized as follows. Section 2 introduces the Fractal component model and the concepts related to Attribute-Oriented Programming. Section 3 introduces the motivation of our work and illustrates it on a simple example. Section 4 presents the Fraclet annotation framework. Section 5 addresses the implementation issues related to our work. Section 6 performs some evaluations. Section 7 compares with related work. Finally, Section 8 concludes and presents some perspectives.

Background

This section first introduces the Fractal component model and then it presents the Attribute-Oriented Programming principles.

The Fractal Component Model

The hierarchical Fractal component model uses the usual component, interface, and binding concepts [START_REF] Bruneton | An Open Component Model and Its Support in Java[END_REF]. A component is a runtime entity that conforms to the Fractal model. An interface is an interaction point expressing the provided or required methods of the component. A binding is a communication channel established between component interfaces. Furthermore, Fractal supports recursion with sharing and reflective control [START_REF] Bruneton | Recursive and Dynamic Software Composition with Sharing[END_REF]. The recursion with sharing property means that a component can be composed of several sub-components at any level, and a component can be a subcomponent of several components. The reflective control property means that an architecture built with Fractal is reified at runtime and can be dynamically introspected and managed. Fractal provides an Architecture Description Language (ADL) [START_REF] Medvidovic | A Classification and Comparison Framework for Software Architecture Description Languages[END_REF], named Fractal ADL, to describe and automatically deploy component-based configurations.

The Fractal component model is already applied at any software granularity from operating systems (e.g., Think [START_REF] Fassino | Think: A Software Framework for Component-based Operating System Kernels[END_REF]) to middleware (e.g., GoTM [START_REF] Rouvoy | Towards Context-Aware Transaction Services[END_REF], DREAM [START_REF] Leclercq | DREAM: A Component Framework for Constructing Resource-Aware, Configurable Middleware[END_REF]), and application servers (e.g., JOnAS à la carte [START_REF] Abdellatif | Enhancing the Management of a J2EE Application Server using a Component-Based Architecture[END_REF]). The simple application depicted in Figure 1 will be used in this paper to illustrate the overhead induced by CBSE. This application is composed of a component Client and a component Server. These two primitive components are contractually bound by the interface Service, named s, that describes the required and the provided operations of the components Client and Server, respectively. The components are included in the composite component HelloWorld, which exports the interface Runnable, named r, provided by the component Client.

Attribute-Oriented Programming

Attribute-oriented programming is a program-level marking technique. Basically, developers can mark program elements (e.g., classes, methods and fields) with annotations to indicate that they maintain application-specific or domain-specific semantics [START_REF] Wada | Modeling Turnpike Frontend System: A Model-Driven Development Framework Leveraging UML Metamodeling and Attribute-Oriented Programming[END_REF]. For example, some developers may define a logging annotation and associate it with a method to indicate the method should implement a logging function, while other developers may define a web service annotation and associate it with a class to indicate the class that would implement a Web Service. Annotations separate application's business logic from middleware-specific or domainspecific semantics (e.g., logging and web service functions).

By hiding the implementation details of those semantics from program code, annotations increase the level of programming abstraction and reduce programming complexity, resulting in simpler and more readable programs. The program elements associated with annotations are transformed to more detailed programs by a supporting tool (e.g., generation engine). For example, a generation engine may insert a logging program into the methods associated with a logging annotation. The dependencies towards the underlying middleware are replaced by annotations, acting as weak references. This means that any evolution of the underlying middleware is taken into account by the generation engine and let the program code unchanged. @OP lets you apply continuous integration in CBSE. Continuous integration allows the developer to generate the middleware artifacts at any step of the development of the component. Developers concentrate their editing work on only one source file per component. The deployment metadata is continuously integrated without worrying about updating it. When the development of a component consists of several files, @OP allows the developer to maintain only one of them and the other files are generated automatically. Besides, working with only one file per component gives a better overview of the program code to the developer. Therefore, the developer can concentrate on the business logic and reduce the development time drastically.

Motivation

Although CBSE provides more modularity, configurability, and reusability properties to applications, the use of a given component model introduces also more complexity, more verbosity and redundancy in the information expressed by the developer. Indeed, developing an application using CBSE principles requires to take into account several concerns. These concerns, which are not always related to the business of the application, are illustrated in this paper with the application HelloWorld depicted in Figure 1.

When developing such an application, the first step consists in describing the operations of the interface Service. Figure 2 introduces the operation print that takes a message as parameter (Line 2). This contract ensures that the components Client and Server can communicate. In the second step, the class Client (see Figure 3) implements the interfaces Runnable and BindingController (Lines 4-5). The method of the interface Runnable concerns the business code of the application (Lines 8-10), and the methods of the interface BindingController deals with the technical code related to management of client interface references (Lines 12-24). In the third step, the class Server (see Figure 4) implements the interfaces Service and ServerAttributeController (Lines 34-35). The method of the interface Service represents the provided operation (Lines 39-42). The methods of the interface ServerAttributeController are dedicated to the configuration of the component attributes (Lines 44-55). Besides, the interface ServerAttributeController should define the methods for handling the attributes header and count defined by the component Server (Lines 26-32).

Once the components Client and Server are implemented, their composition can be described using Fractal ADL (see Fig- Figures 2 to 4 represent the minimal piece of Java code required to implement the application HelloWorld using the Fractal component model. Nevertheless, when considering the 56 lines of Java code of this example, 13 lines are related to the control of client interfaces (BindingController interface implementation) and 19 lines are related to the control of the compo-nent attributes (description and implementation of the interface ServerAttributeController). This means that 57% of the Java code handles the technical concerns imposed by the Fractal component model.

Figure 5 represents the minimal piece of XML definitions required to describe the application HelloWorld using Fractal ADL. This language targets to simplify the composition of Fractal components by the use of an higher-level language dedicated to the definition of architectures. Nevertheless, 17 lines of the 28 lines composing the application describe entities that are still expressed in Java (the primitive components Client and Server). This means that 61% of the descriptors are redundant with the information already present in the component implementations.

In summary, the global overhead of the component model is evaluated in this example to 58%. This number encloses either the technical code specific to Fractal, and the information duplicated between the ADL and the implementation language. Concerning the evolution of the application, the modification of the component content (e.g., adding an attribute or a binding) is a time consuming and repetitive task, which can be subject to errors.

The Fraclet Annotation Framework

Given that the main objective is to leverage the Fractal development process, we choose to apply @OP to drastically reduce the size of the program code by factorizing the redundant information as well as the technical properties imposed by the Fractal component model. Therefore, Fraclet provides various annotations to clarify the specificities of the Fractal programming model and the associated generators to produce the Fractal artifacts. After presenting the objectives, an overview of the Fraclet annotation framework is provided.

Objectives of Fraclet

Fraclet should be designed to support program code evolution. This means that, when considering an incremental development process, Fraclet should be able to produce up to date artifacts at any development step.

Then, Fraclet should not introduce an overhead to the program execution compared to an handwritten program code. This means that the efficiency of the execution support should not be affected by the use of Fraclet.

The design of Fraclet is driven by a concern to facilitate its integration by developers that are already using Fractal. This means that, Fraclet should reuse the concepts introduced in the Fractal component model and the associated tools (e.g., Fractal ADL).

Finally, Fraclet should maximize the size of the generated program code, while minimizing the use of annotations. This means that Fraclet should deduce as much as possible of the relevant information from the program code to produce handwritten-equivalent artifacts.

Overview of the Framework

The Fraclet annotation framework is composed of two parts: The annotations and the generators. An annotation is associated to a given program element, while a generator uses one or several annotated program codes to produce an artifact.

Annotations. Fraclet reifies the Fractal technical concepts as a set of dedicated annotations. Basically, an annotation is composed of an identifier and a set of parameters. The value of a parameter can be required, statically defined among a list of allowed values, or deduced from the program code. Table 1 describes the four annotations defined in Fraclet. The @Interface annotation enhances the definition of a Java interface with a Fractal identifier. The @Binding, @Attribute, and @Controller annotations add to a Java Fraclet provides two Java program code generators and two XML definition generators: Attribute controller. It is a Java generator that produces, for each Fractal component defining an attribute, an interface that handles the attributes defined for the Fractal component. This interface contains a getter and a setter method for each attribute defined for the Fractal component.

Component glue. It is a Java generator that produces, for each Fractal primitive component, the non-functional code. This encloses the program code required to implement the methods of the attribute controller interface generated previously and the methods defined in the binding controller interface.

Primitive definition. It is an XML generator that produces, for each Fractal primitive component, a definition of the primitive component compliant with the Fractal ADL tool. This definition defines the interfaces provided and required by the component, the attributes with their initial value or their argument, and the name of the content class implementing the component.

Abstract composite definition.

It is an XML generator that produces, for each Fractal primitive component with at least a client interface, a definition of a composite component containing the associated primitive component, and abstract definitions of its dependencies. The bindings between the client interfaces of the component and the server interfaces of the dependencies are automatically declared. The server interfaces of the component are automatically exported as server interfaces of the composite component.

Revisiting HelloWorld with Fraclet

In this section, the application HelloWorld introduced in Section 2 is revisited using Fraclet.

In Figure 7, the interface Service is annotated with the @Interface annotation to define its default Fractal name (Line 1).

1 /* * @ I n t e r f a c e name =" s " */ 2 public interface Service { The content class Client is annotated with the annotation @Interface to specify that the component provides an interface Runnable whose Fractal name is r (Line 5 in Figure 8). The annotation @Interface can mark a content class if the interfaces implemented by this class are not already marked (e.g., an interface defined in an external library). Then, the service field is marked with the annotation @Binding and named s (Line 7). The signature of the resulting client interface is deduced from the signature of the field, which is Service in this case. The content class Server automatically inherits from the Service annotations (see Figure 9). The fields header and count are marked as Fractal attributes with the annotation @Attribute (Lines 15-18). The name and the argument of these attributes depends on the name of the marked field.

Therefore, the program code related to the management of component attributes and bindings is no more tangled with the business code of the component.

Figure 10 defines the composition of the application Hel-loWorld. Given that the abstract composite generators defines an abstract definition of the application, the developer writes the definition HelloWorld by extending the abstract composite definition that our approach reduces drastically the size of the handwritten program code, while preserving the semantics of the application HelloWorld. An empirical evaluation of our approach is presented in details in Section 6.

Implementation Issues

This section presents two functionally equivalent implementations of the Fraclet annotation framework. The first defines XDoc annotations and uses the XDoclet generation engine to produce the various artifacts required by the Fractal component model. The second defines Java 5 annotations and uses the Spoon transformation tool to enhance the handwritten program code with the Fractal technical properties.

Implementing Fraclet with XDoclet

XDoclet overview. XDoclet1 is an open program code generation engine. It enables @OP for Java by using special JavaDoc tags. This use of JavaDoc tags for attributes formed the original ideas for Java 5 annotations. The program code and the JavaDoc tags are reified as a Java Abstract Syntax Tree (AST) using Qdox2 . Based on Generama3 , XDoclet uses standard template engines such as Velocity 4 and Freemarker5 for generation of text-oriented output, and Jelly6 for XML output. The generation process is driven by the template file, which consults the Java AST of the program code to feed the required information. The function of XDoclet is to seed the generation contexts for these template engines.

XDoclet is supported by XDoclet plugins, which provide taskspecific generation functionality. XDoclet parses the handwritten program code and generates many artifacts such as XML descriptors and program code from it. These files are generated from templates that use the information provided in the program code and its JavaDoc tags.

Fraclet: An XDoclet plugin. To use XDoclet as a generation engine for Fraclet, it is necessary to define an XDoclet plugin. Basically, an XDoclet plugin is composed of two parts: annotations and generators. The annotations defined in XDoclet are special JavaDoc tags appearing in the program code as /** @Attribute */. These annotations enhance the program code with the metadata that is required by the component model but cannot be expressed in the Java code. The use of XDoc tags as annotations does not require any dependency towards a particular library. The Fractal attribute controller interface and component glue are generated using two Velocity templates. The primitive and abstract composite definition generators are implemented as Jelly templates.

The execution of the attribute controller and component glue generators results in the class diagram depicted in Figure 11

Implementing Fraclet with Spoon

Spoon overview. Spoon is a Java 5 open compiler built on top of Javac [START_REF] Pawlak | Spoon : Annotation-Driven Program Transformation -The AOP Case[END_REF]. Spoon provides the user with a representation of the Java AST in a metamodel, which allows both for reading and writing. Using this metamodel and a specific API, Spoon allows the programmer to process Java 5 programs. This processing is implemented with a visitor pattern that scans each visited program element and can apply some user-defined processing jobs called processors. In particular, the processing can be annotation-driven, contrary to XDoclet. Taking advantage of Java 5 features, Spoon also natively provides a framework that allows for the definition of code templates in pure Java. By specifying templates in pure Java, programmers can write them in their favorite Java IDE and benefit from all the advantages that come with it (incremental compilation, completion, syntax highlighting, contextual help, refactoring, wizards, etc.).

Fraclet using Spoon templates and processors. Our second implementation of Fraclet uses Spoon templates and processors to transform the Fractal base program enhanced with Java 5 annotations, and to generate some artifacts such as XML files for Fractal ADL. The main originality of this implementation compared to the XDoclet one is that the base program can be directly transformed by manipulating the metamodel of the base program. As explained in the previous paragraph, Spoon builds a metamodel of the base program (a representation of the Java AST) which allows the reading and writing of program elements. Thus, in this implementation of Fraclet, features can be directly injected into the original classes instead of extending them using inheritance. For example, the getter and setter methods related to the annotation @Attribute (see attribute controller generator in Section 4.2) are injected into the original class. As a matter of comparison, Figure 11 presents the class hierarchy obtained with the XDoclet implementation and Figure 13 shows the class hierarchy obtained with the Spoon implementation. In the first case, new classes FcServer and FcClient are generated to provide the wanted artifacts, whereas in the second case, artifacts are directly injected into original Client and Server classes.

Evaluation

This section aims at evaluating the benefits of using @OP for the development of Fractal applications. Table 2 provides an empirical measure done on the application HelloWorld introduced in this paper. This evaluation confirms the statements claimed in Section 3 because it appears that the use of Fraclet saves 57% of the program code when considering the number of lines of Java source code and 88% of the ADL definitions. Table 2. Empirical measure performed on HelloWorld.

Table 3 provides an empirical measure done on the Comanche web server 7 . This application does not define any attribute and uses only three components with client interfaces. Therefore the overhead of the Fractal component model appears to be limited but the result of the evaluation makes appear that 41% of the Comanche source code can be saved.

Related Work

This section compares our Attribute-Oriented Programming approach to the Generative Programming and Aspect-Oriented approaches already applied in the context of the Fractal component model.

Generative Programming

Integrated Development Environments (IDE), such as Eclipse, already provide program code generators to automatically fill some pieces of program code (e.g., getter and setter methods for a given attribute), but these generators are static and limited. In particular, they are limited to the program code generation and provide only trivial generators. They do not provide a way of either generating methods combining several attributes or external artifacts (e.g., descriptors, configuration files).

Similarly, the Fractal GUI tool is an IDE dedicated to the development of Fractal applications. It allows the developper to graphically design the components of an application. Once the application is fully described, Fractal GUI provides Java code generators to produce automatically skeletons of the component code -i.e., components without business method code. Nevertheless, if the program code evolves once generated, Fractal GUI is not able to retrieve the evolution of the program code to integrate them.

Fraclet provides a solution to support continuous integration of Fractal non-functional code in the business code. The component artifacts are automatically generated from the current version of the program code. This approach supports either trivial generators (e.g., getter/setter methods), or advanced generators (e.g., binding controller), or external artifacts (e.g., ADL definitions) using a small set of program code annotations. This approach is also complementary to IDEs approaches by providing reverse engineering capabilities to the program code generated by tools such as Fractal GUI.

Aspect-Oriented Programming

Aspect-Oriented Programming (AOP) aims at modularizing crosscutting code into systems [START_REF] Kiczales | Aspect-Oriented Programming[END_REF]. It is motivated by the realization that there are concerns not well captured by current programming techniques. To overcome this issue, AOP proposes artifacts to modularize them by the use of advising and code introduction (inter-type declaration in AspectJ). The advising term refers to the traditional pointcut/advice model of AOP. Advices implement the crosscutting concern which is then woven to the base system by use of pointcuts.

A pointcut is able to pick out a set of join points (point in the execution of a program) where the advice codes apply. The introduction term refers to another feature of AOP, which allows the injection of new features into the base code, namely introducing a new field in a class, or it can force a class to implement a particular interface along with an implementation of that interface.

In AOKell, an implementation of the Fractal component model in Java, which uses AspectJ advising and introduction to implement the level of control of components [START_REF] Seinturier | A Component Model Engineered with Components and Aspects[END_REF], introduction is used to inject the implementation of control interfaces into content classes of components. Advising is used to implement some control interfaces, which require interception of interface calls such as the life cycle control interface which has to block calls on stopped components. Similarly to Fraclet, AOKell is able to inject the binding control interface implementation into components. Although the introduction mechanism seems perfectly well suited for this task, one major feature is missing. Indeed, with introduction the implementation of an interface can be forced, but the interface itself cannot be generated. It has to be provided by the aspect programmer. Thus, AOP introduction mechanism can only inject new features into existing classes but cannot generate new entities such as interfaces or classes from scratch. Moreover Fraclet is not tightly coupled to a particular implementation of Fractal. This means that Fraclet can be used either with AOKell or Julia [START_REF] Bruneton | An Open Component Model and Its Support in Java[END_REF].

The work presented in [START_REF] Schiavoni | A Posteriori Defensive Programming: An Annotation Toolkit for DoS-Resistant Component-Based Architectures[END_REF] proposes an annotation toolkit that allows building DoS resistant component-based systems. The proposed mechanism handles the robustness concern as separated concern. This concern is identified on the component interfaces at the architecture level, making it transparent to the developer of a component. Therefore, the annotations defined in this work are not used in the source code of the component but are applied in an a posteriori approach using the Fractal ADL tool. While bringing annotation benefits to the architecture level of application, this approach, based on AspectJ, is limited to the injection feature and does not support the generation of external artifacts. The objective of Fraclet is to facilitate the development of Fractal applications, while providing an easy and abstract syntax for programming the component's content. This approach hides the technical specificities of the Fractal component model to the developer generates automatically most of the artifacts required by the model (API, descriptors). Moreover, Fraclet does not require any modification of existing Fractal tools.

Conclusion and Perspectives

This paper introduced the Fraclet annotation framework. We have shown that Fraclet makes the development of Fractal applications easier by factorizing redundant information and non-functional code, which is possible through the use of annotations. These annotations are dedicated to the Fractal component model specificities -i.e., interface, binding, and controller. The associated generators interpret the annotated program code to produce various kinds of artifacts (e.g., Java code, XML definitions). This approach allows the developer to save 50% of the traditional Fractal program code by hiding the implementation of the non-functional code. Two implementations of Fraclet are available: (1) using XDoc annotations and the XDoclet generation engine and (2) using Java 5 annotations and the Spoon generation engine.

The perspectives on this work enclose the extension of Fraclet to support tools such as the Monolog logging framework 8 and the Fractal Explorer tool. Monolog provides logging facilities to Fractal components. The goal of Fraclet will be to make easier the use of the loggers by generating either the configuration file required by the Monolog framework and the piece of code used to initialize a Monolog logger. Fractal Explorer is a graphical administration con-sole that allows users to dynamically interact on their applications. Fractal Explorer allows the developer to customize the graphical user interface with the definition of an explorer plugin. An explorer plugin encloses the definition of a set of icons, panels, and actions for a given application. Nevertheless, the development of such a plugin can become a fastidious task for most of the developers. Thus, the goal of Fraclet will be to make easier the personalization of the Fractal Explorer thanks to a set of dedicated annotations. These annotations will take in charge either the generation of the explorer configuration file and the generation of some trivial actions. Another perspective for Fraclet is its integration in the Fractal GUI tool. This integration would ensure the backward compatibility between the program code and the graphical representation of the architecture provided by Fractal GUI when the program code evolves.

Availability. Fraclet is freely available under an LGPL licence at the following URL: http://fractal.objectweb.org/

Figure 1

 1 Figure 1 illustrates the different entities of a typical Fractal component architecture. Thick black boxes denote the controller part of a component, while the interior of the boxes corresponds to the content part of a component. Arrows correspond to bindings, and tau-like structures protruding from black boxes are internal or external interfaces. Internal interfaces are only accessible from the content part of a component. External interfaces appearing at the top of a component represent reflective control interfaces such as the component controller (c), the lifecycle controller (lc), the binding controller (bc), the content controller (cc), and the attribute controller (ac) interfaces.

Figure 1 .

 1 Figure 1. The Fractal component HelloWorld.

1Figure 2 .

 2 Figure 2. Implementing the interface Service.

4 public class Client 5 implements 6 private

 56 Runnable , B i n d i n g C o n t r o l l e r { Service s ; // I n t e r f a c e Service named s .

15 publicFigure 3 .

 153 Figure 3. Implementing the component Client.

12 < 13 < 14 < 15 < 16 <Figure 5 .

 12131415165 Figure 5. Describing the components composing HelloWorld.

Generators.Figure 6 .

 6 Figure 6. Overview of Fraclet generation engine.

Figure 7 .

 7 Figure 7. Annotating the interface Service.

5 8 protected 12 } 13 }Figure 8 .

 812138 Figure 8. Annotating the component Client.

Figure 9 . 2 <Figure 10 .

 9210 Figure 9. Annotating the component Server.

Figures 7 to 10

 10 Figures 7 to 10 show that our approach reduces drastically the size of the handwritten program code, while preserving the semantics of the application HelloWorld. An empirical evaluation of our approach is presented in details in Section 6.

  Figures 7 to 10 show that our approach reduces drastically the size of the handwritten program code, while preserving the semantics of the application HelloWorld. An empirical evaluation of our approach is presented in details in Section 6.

  . The class FcClient (resp. FcServer) extends the content class Client (resp. Server) to inherit from the business code of the component. The class FcClient implements the interface BindingController specified by the Fractal component model to allow its client interfaces to be bound to any compatible server interfaces. The class FcServer implements the interface Server-AttributeController generated by the attribute controller generator to support the dynamic reconfiguration of the component attributes. The interface ServerAttributeController must extend the AttributeController as specified in Fractal.

Figure 11 .Figure 12 .

 1112 Figure 11. XDoclet implementation: The UML class diagram. The execution of the generators of the primitive and abstract composite definitions results in the file architecture depicted in Figure 12. The primitive definition Server extends the abstract definition Service to declare the list of provided interfaces. The primitive definition Client is used by the abstract composite definition ClientComp to define the client component contained in this composite. The abstract composite definition ClientComp refers also to the abstract definition Service to resolve the dependency of the client component.

  Submission to the 1st International ECOOP Workshop on the Fractal Component Model 5 2016/8/11

Figure 13 .

 13 Figure 13. Spoon implementation: The UML class diagram.

Table 1 .

 1 Submission to the 1st International ECOOP Workshop on the Fractal Component Model 3 2016/8/11 Overview of Fraclet annotations field the semantics of a client interface, a component attribute, and a component controller, respectively.

	Annotation	Location Parameter	Description	Contingency Default Value
	@Interface	Class	name	server interface name	required	-
			signature	server interface signature	optional	signature of the Java interface
	@Binding	Field	name	client interface name	optional	name of the Java field
			signature	client interface signature	optional	signature of the Java field
			cardinality	client interface cardinality (singleton|collection)	optional	singleton
			contingency client interface contingency (mandatory|optional)	optional	mandatory
	@Attribute	Field	name	component attribute name	optional	name of the associated field
			value	component attribute initial value	optional	-
			argument	argument name in the component definition	optional	attribute name
	@Controller	Field	name	component controller name to access	optional	component

Table 3 .

 3 Empirical measure performed on Comanche Web Server.

	Program	Unit	Fractal Fraclet	Gain	Rate
	Code		A	B	G = A -B	G/A
	Java	files	12	12	0	0 %
	ADL	files	19	6	13	68 %
	Java	lines	254	173	81	32 %
	ADL	lines	88	38	50	57 %
	Source	bytes	124 K	72 K	52 K	41 %

The XDoclet project: http://xdoclet.codehaus.org/

The QDox project: http://qdox.codehaus.org/

The Generama project: http://generama.codehaus.org/

The Velocity project: http://jakarta.apache.org/velocity/

The Freemarker project: http://freemarker.sourceforge.net/

The Jelly project: http://jakarta.apache.org/commons/jelly/

The definition of the Comanche web server is available at the following URL: http://fractal.objectweb.org/tutorial/index.html

Monolog project: http://monolog.objectweb.org/

System . out . println ( this . header + msg );


S Ducasse

A Plantec
email: alain.plantec@univ-brest.fr

IWST 2016 Pre ACM Digital Library Version Pragmas: Literal Messages as Powerful Method Annotations

Often tools need to be extended at runtime depending on the availability of certain features. Simple registration mechanisms can handle such a situation: It often boils down to represent an action and describe such action with some metadata. However, ad-hoc registration mechanisms have some drawbacks: they are often not uniform and do not fit well with code navigability. In addition, metadata is not automatically synchronized with the data or behavior it describes. In this article we present the notion of pragmas, method annotations, as it was introduced in VisualWorks and now it is an important extensibility mechanism of Pharo. We present some examples of pragmas within Pharo.

Introduction

Often tools need to be extended at runtime depending on the availability of certain features. This is typically the case for menubar offering access to currently loaded tools. Before pragmas were introduced in VisualWorks [START_REF]Cincom Smalltalk[END_REF], the launcher's menubar was static and had lots of disabled entries for launching tools that were sold separately such as DLLAnd-CConnect. It was a clear sign that a registration mechanism was missing at method level.

Simple registration mechanisms can handle such a situation: It often boils down to represent an action and describe such action with some metadata [START_REF] Demeyer | Object-Oriented Reengineering Patterns[END_REF]. However, ad-hoc registration mechanisms have some drawbacks:

• They often are not uniform. The user has to adapt to each of them.

• They do not fit well with code navigability and their existence and use may be difficult to discover.

[Copyright notice will appear here once 'preprint' option is removed.]

• One important aspect with registration mechanisms is how to keep metadata and method in sync. With ad-hoc registration mechanisms, metadata is not automatically synchronized with the data or behavior it describes. It is often the responsibility of the user to keep such information up to date.

• Finally ad-hoc registration mechanisms do not fit well with the variability of arguments.

In this article we present pragmas, method annotations, as it was introduced in VisualWorks [START_REF]Cincom Smalltalk[END_REF][START_REF] Wuyts | Unanticipated integration of development tools using the classification model[END_REF] and now it is an important extensibility mechanism of Pharo [START_REF] Black | Pharo by Example. Square Bracket Associates[END_REF]. Method pragmas are method level annotations that integrate smoothly with the Smalltalk syntax and tools.

The outline of the paper is the following: first we present a simple set of requirements for code annotations. Then we present the history and motivation behind the first implementation of pragmas. In the subsequent sections we present the API and propose an analysis of pragmas. Finally, we present some examples of pragmas within Pharo. In particular, we show that while pragmas as method annotations are inherently static constructs, they are the basis to build dynamic solutions that react to method annotation changes.

An Analysis for Program Annotations

A good use of method annotations is to associate metadata with a particular method. Building an ad-hoc registration mechanism is not complex. Typically, ad-hoc registration mechanisms use a collector object holding a list of object representing metadata. Users should explicitly call the collector to register to it and the system using the metadata uses such collector. However such practice is a problem because the method and its metadata are not automatically kept in sync. So another layer of triggering should be put in place to make sure that each time a method changes its metadata is (or not) updated. The programmer has to look in different places to find and update the information. Now we list the properties that a good program annotation mechanism should exhibit.

Annotation Requirements.

Here is a simple list of requirements for program annotation mechanisms.

• Uniformity. Introducing a special syntax for annotations can lead to large engineering efforts and should be minimized when possible.

• Handle variability. A good annotation system should be able to handle the variability of the annotation needs. Since method annotations are static in the sense that they annotate program elements, they cannot access runtime elements such as receiver and method arguments.

• Discoverable/Searchable. The introduction of a new mechanism should also consider the impact on the discovery of such new constructs. When cross-referencers are more advanced than mere textual matching (e.g. message sends), it is important that annotations can be found as a high-level concept.

• Synchronized metadata. The annotation and its associated element should be kept synchronized. The distance between the annotation and its element should be as short as possible to make sure that the users can understand that an element is annotated.

• Any type of program element. An annotation mechanism should be able to annotate any program elements.

We now present method pragmas, a method level annotation system integrating smoothly with the Smalltalk syntax and the tools, and keeping minimal distance with the annotated method. But we start first with a little history of pragmas, since pragmas have been designed around 2003 for Vi-sualWorks.

Some History First

Steve Dahl and Eliot Miranda developed pragmas at Parc-Place, with Vassili Bykov adding abstractions for accessing them. The first step was to redesign some ugly class-side code to set unwind bits in ensure: and ifCurtailed: [START_REF]Draft American National Standard for Information Systems -Programming Languages -Smalltalk[END_REF][START_REF] Bergel | Deep Into Pharo[END_REF] by a pragma the compiler would recognize and set the bits itself. The first real use was to make the VisualWorks launcher's menus extensible. With pragmas the launcher's menu was defined with the base system's tools and then extended as each tool package was loaded, or cut-back as each tool was unloaded. This development decoupled the launcher from introducing new tools.

VisualWorks then started using pragmas for the browser and one could plug-in a single tool without redefining the browser's menu methods, which decoupled each extension. All this was done in the context of the parcel system [START_REF] Wuyts | Unanticipated integration of development tools using the classification model[END_REF]. pragmas allowed one to decouple these tools where they collided in places like menu definition and tool registration.

Then, Tami Lee, who was managing the COM connection that turned a VisualWorks image into a COM server, became the first "user" of pragmas. She used pragmas to replace a lot of class-side methods that defined the signatures of methods that comprised the server. One could define the COM signature for a method in the method itself, and the class side lost about three separate methods that defined all that metadata. One could read the server method itself and understand its semantics without having to consult the class-side methods. One didn't have to know that there was metadata hidden on the class side because it was defined in the method itself.

Then Vassili Bikov used it for the inspector framework, Trippy, which was a huge improvement over the old Inspector framework, again resulting in a much more pluggable, decoupled and extensible system. Vassili also added the abstractions for accessing pragmas in methods.

Then VisualWorks added checking so that one could restrict the compiler to accept only legal pragmas for a given class. But if we defined the legal pragmas in a class-side method, say legalpragmas, then this would be exactly the kind of single point for extensions that causes collisions between packages, each of which might want to add its own set of pragmas. The solution was to use a pragma to mark a class-side method as defining a set of legal pragmas for a class. One could have more than one method defining a set of legal pragmas; packages wishing to add their own cool pragmas were decoupled.

Pragma: Method Annotation for Smalltalk

pragmas are a Smalltalk-centric way of adding arbitrary metadata to methods; Smalltalk-centric in that a pragma is a Message instance. It may be queried for senders, executed, etc, and it can be parsed using the standard compiler -they add no new syntax.

A pragma represents the occurrence of an annotation in a compiled method. A pragma is a literal message pattern that occurs between angle brackets at the start of a method after any temporaries. A common example is the primitive pragma: the argument identifies the Virtual Machine primitives to be executed.

LargeInteger >> // anInteger "Primitive. Divide the receiver by the argument and return the result. Round the result down towards negative infinity to make it a whole integer. Fail if the argument is 0. Fail if either the argument or the result is not a SmallInteger or a Large-PositiveInteger less than 2-to-the-30th (1073741824)." <primitive: 32> ^super // anInteger But one can add one's own and use them as metadata attached to a method. Because pragmas are messages, one can browse senders and implementors and perform them. One can query a method for its pragmas by sending it the pragmas message, which answers an Array of pragma instances, one for each pragma in the method. A pragma holds information about its defining class, method, its selector, as well as the information about the pragma keyword and its arguments.

Instances are retrieved using one of the pragma search class methods.

In Pharo, the expression : browses all non-primitive methods with pragmas.

Discovering the API

In this section, we present the essential aspects of the Pragma API as in Pharo [START_REF] Black | Pharo by Example. Square Bracket Associates[END_REF]. We start with the static navigation and then we show how pragmas can be executed.

Declaring a Pragma. First a pragma should be declared or attached to a method using the < > syntax. Such syntax is the same as that used to mark primitive methods [START_REF] Goldberg | Smalltalk 80: the Interactive Programming Environment[END_REF]. Here we see that the method gtInspectorColorIn: of the class Color is annotated with the pragma gtInspectorPresentationOrder: 30. This pragma takes 30 as argument.

Color The pragma syntax follows that of message sends. But since pragmas are static code annotations their argument can only contain literal objects.

Accessing method annotation. A method can be annotated by several pragmas. We can access a pragma from the annotated method using the pragmas message (see Figure 1).

pragma := (Color >> #gtInspectorColorIn:) pragmas first. pragma arguments > 30

Once we get the pragma object itself we can access its selector using the message keyword (which should be renamed selector to match the message API).

pragma keyword > #gtInspectorPresentationOrder:

Accessing annotated method. From a pragma we can access the method it annotates using the message method. The message selector returns the method selector. As we will discussed in following section such API could be improved. Querying pragmas. pragmas act as a registration mechanism since they can be queried at different scopes (full system, package, class). Once pragmas are collected, the programmer can have access to the pragma itself and its annotated method. The Pragma class provides some functionality to query the methods. The following expression gathers all the pragma named #alarm: limited to the class Pragma itself.

Pragma allNamed: #alarm: in: Pragma

The next expression shows that we can scope the lookup to a branch in the hierarchy.

Pragma allNamed: aSym from: Point to: Object

The PragmaCollector tool developed in Pharo offers more advanced querying facilities and change notifications.

Executing a Pragma. A pragma is not just a method annotation. Pragmas are similar to messages1 . Similarly to a message, a pragma can also be executed once provided with a receiver. The message sendTo: anObject allows one to execute pragma by providing one receiver.

Imagine that we have the following code: In a class we define the method test. This method is annotated with a pragma named alarm:. Then we define a class named Alarmer. This class defines the method alarm:.

AClass >> test <alarm: 'Executing pragma' > ^12

Alarmer >> alarm: aString UIManager default alert: aString

The following code snippet then asks the pragma associated to the method AClass»#test to execute itself with an instance of Alarmer. As a result, the alarm: method is executed.

(AClass >> #test) pragmas first sendTo: Alarmer new

The class Pragma defines another method supporting its execution. The message Pragma»#withArgumentsDo: aBlock executes a block on the values of the pragma arguments. We can get a similar result than with the message sendTo: using the message withArgumentsDo: as follows:

(AClass >> #test) pragmas first withArgumentsDo: [ :each | UIManager default alert: each ]

Managing pragmas Dynamically with the PragmaCollector

Querying pragmas can be achieved by using dedicated services provided by the Pragma class. But a tool may depend on the actual set of pragmas. In such a situation, a tool may need to adapt its internal state whenever a method containing a particular pragma is added, removed or updated. This is the role of the PragmaCollector and we describe it now. This section describes the PragmaCollector and the pattern that is typically used by tools to dynamically update their internal state according to the actual set of pragmas.

The PragmaCollector

PragmaCollector responsibilities are to store a set of particular pragma instances and to dynamically keep its set of pragmas up-to-date. The selection of pragmas is based on a filter which can be passed as a valuable with one argument at instantiation time. As an example, the following code shows how to instantiate a PragmaCollector to get the actual set of primitives. At initialization time, a PragmaCollector registers itself as a SystemAnnouncer subscriber. (SystemAnnouncer is the central notification for system events such as class creation, method modifications, etc). The consequence is that a particular message is sent to the PragmaCollector each time a method is added, removed or updated in the system. When such an event occurs, an announcement is sent to all the registered PragmaCollector instances. Then a PragmaCollector may update its set of pragmas accordingly if the method is defined with a valid pragma according to the PragmaCollector filter. As an example, the sequence diagram of Figure 2 depicts how a PragmaCollector can update its set of pragmas dynamically when a method is added in the system.

A PragmaCollector also owns an announcer that registers objects which need to be notified each time the PragmaCollector set of pragmas is changed. PragmaAnnouncement is the superclass of all pragma related announcement classes. In the case of an addition, removal or update, the corresponding announcement classes are, respectively, PragmaAdded, PragmaRemoved and PragmaUpdated. Thus, a tool can register itself as a listener of its PragmaCollector announcer to be able to adapt its internal state.

The following presents a pattern which is typically used by tools to keep their internal state up-to-date. The Pharo root menu building uses pragmas. The menu tree is built by evaluating all the class methods declared using the pragma <worldMenu>: the receiver is the class owning the method and a menu builder is passed as argument. A pragma without argument is used and the annotated method is called with a builder as argument: this pattern is used to handle the fact that building menu can have multiple exclusive parameters (See Section 7.2 for another application of this pattern).

A menu builder builds and stores a menu tree. It uses a PragmaCollector instance to get the actual set of <worldMenu> annotated methods. Note that pragmas are spread over the classes supporting a modular design.

Some Pragma Applications

Pragmas are heavily used both in VisualWorks and Pharo. The examples cover different categories. Pragmas are used for pluggable UIs (extensible menus, inspectors, setting declaration) where the method specifies an operation within the framework and the pragma specifies where and how the operation fits within a UI. Pragmas are also used as metadata used by a compilation system: the VisualWorks COM server exports Smalltalk methods through COM to make a Visual-Works COM server. The types for Smalltalk methods used to be specified in a single class-side initialize method. The use of pragmas allowed the metadata to be added to each server method, allowing the system to be extensible again.

In the following we present examples that are heavily used in Pharo: the customization of inspector panes and setting declarations.

Use 1: GTInspector Panes

GTInspector is an extensible inspector. It uses pragmas to extend classes with the different views that are exposed the user in the inspector. The following methods show three of the views exposed by the CompiledMethod class. Figure 3 shows some of the different panes that the programmer has access to.

Use 2: Settings

A setting is a description of a preference value. To be viewed and updated through the Setting Browser, a preference value must be described by a setting. Such a setting is built by a particular method tagged with a specific pragma. This specific pragma <systemsettings> serves as a classification tag which is used to automatically identify the method as a setting.

One Setting. Let's take the example of the caseSensi-tiveFinds preference. It is a boolean preference which is used for text searching. If it is true, then text finding is case sensitive. This preference is stored in the CaseSensitiveFinds class variable of the class TextEditor. Its value can be queried and changed by, respectively, TextEditor class»caseSensitiveFinds and TextEditor class»caseSensitiveFinds: given below: The domain of preferences is large: To describe all possible preference kinds (color, strings, boolean, url, emails) and default values, we would need a lot of pragma parametersmany of which would not be relevant for certain settings. The method definitions below show variations of such parameters.Therefore The Settings framwork uses pragmas as a simple tag and associate this pragma usae with a builder whose responsibility is to offer an adequate and flexible API to specify settings.

In the method declaring a setting, the pragma <system-settings> identifies the method as declaring a setting. The Settings framework invokes this identified method with a builder that the method uses to define the actual setting object. A Layered Architectural as Benefit. The use of pragmas supported the building of a layered architecture. Description of customization point. In Figure 5, the package UI-Basic Setting defines a method. The important point is that the method declaring the setting does not refer directly to Setting classes but describes the setting using a builder. This way the description could even be present in the UI-Basic package without introducing a reference.

Collecting settings for user presentation. The Setting Browser collects settings by querying pragmas and uses their description to change the value of preferences. The control flow of the program and the dependencies are always from the package Settings to the package that has preferences and not the inverse.

Analyzing pragmas

Now we analyze the pragmas both from a conceptual and implementation point of view.

First class method annotations

We now evaluate how pragmas answer the requirements for method annotations.

Uniformity. Pragmas do not introduce any new syntactical elements and as such their integration and tooling is facilitated. In particular, no special handling has been necessary to be able to query pragmas as message senders. Pragmas are Handle variability. Pragmas are generic enough to handle the use cases in the Pharo system (as well as the ones of VisualWorks). Since pragmas are static annotations, only literal objects can be used as parameters. However, since we can invoke the associated methods, it is possible to use argument-less pragmas and pass an argument to the method that acts as a builder (The Setting framework [START_REF] Bergel | Deep Into Pharo[END_REF] uses this technique -see Section 6.2 for example). In Pharo 50 there are 143 different pragmas for 4337 annotations with the following distribution based on their arity: 95-0, 30-1, 11-2, 5-3, 1-4 and 1-5. The pragma (preference:category:description:type:) with 4 arguments with 4 elements is not used in Pharo but a behavior compatible with the Squeak settings. One of the biggest limits of pragmas is that they do not handle class annotations.

Discoverable/Searchable. Pragmas are perfectly discoverable using normal message browsers. The tools managing the navigation in the IDE are able to handle pragmas. As already mentioned, SystemNavigation queries return messages as well as pragma usage. Debugging pragmas has nothing really specific, a developer can query all the annotated methods with a given pragma and use the Pragma API to access all the data necessary to debug.

Synchronized metadata. Metadata, when it cannot be extracted automatically from the entity it describes, can always be out of sync. When metadata can be extracted directly from the entity it would describe then there is no need to have metadata expressed since it would duplicate such information and lead to potential desynchronization. While pragmas per se do not ensure that methods and their annotations will not be desynchronized, their locality and minimal distance to the entity they describe is a good incentive for the programmers to make sure that a method and its annotations are kept in sync. As a summary, pragmas favor synchronized metadata because pragmas are embedded in their methods. In addition Pharo offers automatically trigger notifications on pragma modifications. This help building advanced behavior such as adding a pane to open inspectors as soon as we define the method that describes the pane, adding or removing a menu entry, etc.

Any type of program element. Pragmas are limited to method annotations. Class and package annotations are missing. Developers can annotate class methods to represent class and package annotations. However, annotating class methods to define class annotations relies on the interpretation by the pragmas user, since it could conflict with the annotation of a single class methods.

About decoupled information

Using a monolithic design where all metadata is described in a single place makes sure that the programmer fully control the order of the declaration. Such control comes at the price of offering a modular way to build applications. Such order may be not relevant in certain cases but it is important for example in UI elements such as menu items or inspector panes.

When pragmas are used to describe menu items or panes, the pragma collector client has several possibilities to sort items: order given by the collection of the pragmas or any alphabetic sort based on a pragma properties. When order is relevant, often metadata includes an explicit order. In case of conflict a local ordering is done. Such practice is not tight to pragmas, metadescription frameworks such Magritte [START_REF] Ducasse | Metaenvironment and executable meta-language using Smalltalk: an experience report[END_REF][START_REF] Renggli | Magritte -meta-described web application development[END_REF] use the same simple strategy.

For a polymorphic API with Message

It is a bit confusing that while a pragma is supposed to be using the message syntax it does not follow the Message API. keyword should be renamed selector and selector should be renamed methodSelector as in Figure 6. Hence methodSelector returns the annotated method selector, similarly method-Class returns the class of the annotated class and selector returns the selector of the pragma.

Compile-time vs. Runtime

The question of pragma validation at compile-time is worth discussions. Most pragmas are annotations that are queried at runtime and do not lead to any computation at compiletime. However, some pragmas do cause processing at compile time. For example, an FFI signature pragma can be checked at compile-time. By default, there is no type or arity checking in the current implementation. It follows the general that no message is Smalltalk is checked at compiletime. When a new method with different arity (and name) is defined, the compiler just compiles it without checking that it may not correspond to a given family. The same applies to pragmas. If checking would be required, it could be possible to define Pragma 'Class' or 'Signature' and the compiler could check whether a pragma is compliant with its Signature.

Coupled Actions: Declaration and Execution

The ability to execute a pragma is a key element to its design. Indeed in many use cases the pragma helps specify the method to be executed. This is the case in inspector, settings, and menu extensions.

The method is a component to be included in some larger structure, e.g., it is an action method on a menu, or it is an implementation of a pane in an inspector. The pragma is the message to be sent to the object that manipulates that larger structure to add the method to it. This is how menu pragmas work in VisualWorks and Pharo. There is a menu builder object. To add a method to a menu (and which menu is described by the pragma) the menu builder sets the method as its current method and then performs the pragma. In VisualWorks, the parameters in the pragma allow the MenuBuilder to add the method in the right way to the menu. In Pharo, the pragma is without argument but the method has an argument that acts as a builder. The design is similar in the Settings framework [START_REF] Bergel | Deep Into Pharo[END_REF]. The execution of the pragma is what actually adds the method to the menu. So it's a combination of specification and execution.

Related Work

Java, C# and Javascript support annotations and used them really frequently. In Java, a method annotation is defined by @ For example, the following @Test declares that the method is a test method. Annotations are before methods. For exemple, JUnit requires an annotation before test methods: @Test Public void the method()

In Java, annotations are defined directly close to the language elements they target. Annotations can target classes, methods, variables, parameters and packages but also to local variables, method parameters, packages, even other annotations and also some Java specific program elements such as constructors, interfaces, enums 2 .

Java defines a set of annotations that are built into the language. For example, @Override checks that the method is an override. @Deprecated marks the method as obsolete. @SuppressWarnings instructs the compiler to suppress the compile time warnings specified in the annotation parameters. In Java 8, new type annotations has been introduced @NonNull, @ReadOnly, @Regex, @Tainted and @Untainted, @m (for measure). Java SE 8 allows type annotations anywhere that a type is used. Previously, annotations were only allowed on definitions.

Annotations can be applied to other annotations such as @Retention to specify how the marked annotation is stored (whether in code only, compiled into the class, or available at runtime through reflection), @Target marks another annotation to restrict what kind of Java elements the annotation may be applied to.

Annotations are either used at compile-time or runtime. The annotation has to be itself annotated to be available at runtime. For example, the following specifies that the annotation interface is available at runtime and can be applied to packages, fields, constructors, types and methods. @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE, ElementType.METHOD, Element-Type.CONSTRUCTOR, ElementType.PACKAGE, ElementType.FIELD) public @interface Note String value(); Priority priority() default Priority.MEDIUM;

Annotations without the meta-annotation are not available on runtime.

Statically we can manipulate annotation using the APT (annotation processing tool). It allows you to write a meta program that can get information of the classes and the annotations they have. This is intended to be used in the generation of code, documentation and any infrastructure previous to the running of your code. APT is often used as a preprocessor.

The other way is to use the reflection objects provided by the environment, a developer can ask a class all the annotated things (methods, the class it self and attributes) and perform all the sort of reflection Java lets you perform. The programmer can only access known classes (by reference or by name). In Java developers use classloaders to access all the classes and then access their annotations.

Conclusion

In this paper we presented pragmas: method annotations that act as statically described message sends. Pragmas do not require Smalltalk syntax modification and are fully integrated in the IDE and tools supporting code navigation. In addition, we presented the PragmaCollector: a tool that dynamically keeps a set of pragmas up-to-date. Each time a method is recompiled or redefined the pragmas are updated. We presented two use cases deployed in Pharo since a couple of years. Finally we showed that pragmas support the design of modular libraries and as such more modular systems.

(

  PragmaCollector filter: [:pragma | pragma keyword = 'primitive:']) reset

Figure 2 .

 2 Figure 2. A sequence diagram for the method adding case

Figure 3 .

 3 Figure 3. GTInspector in action. Three of the different views of a compiled method exposed to the developer.

  TextEditor class >> caseSensitiveFinds ^CaseSensitiveFinds ifNil: [CaseSensitiveFinds := false] TextEditor class >> caseSensitiveFinds: aBoolean CaseSensitiveFinds := aBoolean CodeHolderSystemSettings class >> caseSensitiveFindsSet-tingsOn: aBuilder <systemsettings> (aBuilder setting: #caseSensitiveFinds) target: TextEditor; label: 'Case sensitive search' translated; description: 'If true, then the "find" command in text will always make its searches in a case-sensitive fashion' translated; parent: #codeEditing.

Figure 4 .

 4 Figure 4. The Case sensitive search setting.

  Figure 5 shows three packages: The Settings package defines tools to manage settings such as a Setting Browser that the user opens to change her/his preferences. It uses descriptions packaged in package UI-Basic Setting. Such descriptions describe behavior of elements packaged in package UI-Basic. The class RealStateAgent follows the behavior expressed in its class variable UsedStrategy.

Figure 5

 5 shows important points of the architecture put in place: The Settings package can be unloaded and a package defining preferences does not depend on the Settings package. This architecture is supported by the following points: Customization points. Each application customization points should be defined. In Figure 5, the class Real-StateAgent of the package UI-Basic defines the class variable UsedStrategy which defines where the windows appear. The flow of the package UI-Basic is modular and self-contained: the class RealStateAgent does not depend on the Settings framework. The class RealStateAgent has been designed to be parameterized.

Figure 5 .

 5 Figure 5. A package declares and uses customization points as variables. As an example, UsedStrategy is declared as a class variable of RealEstateAgent. Such customization points are described with Setting instances that are created by the automatic running of setting declaration methods. The Setting Browser collects the setting instances by querying pragmas and presents them to the user.

Figure 6 .

 6 Figure 6. Suggested API polymorphic to Message API.

  SystemNavigation new browseAllSelect: [:m| m pragmas notEmpty]browses all methods with pragmas in the system. The expression:

	SystemNavigation new
	browseAllSelect: [:m| m primitive isZero
	and: [m pragmas notEmpty]]

  Here we show two examples one in WorldState and one in StartupPreferences-

	Loader.
	WorldState class >> quitItemsOn: aBuilder
	<worldMenu>
	(aBuilder group: #QuitPharo)
	order: 9999;
	with: [
	(aBuilder item: #'Save')
	target: self;
	selector: #saveSession;
	help: 'save the current version of the image on disk';
	keyText: 'S';
	icon: Smalltalk ui icons smallSaveIcon.
	(aBuilder item: #'Save as...')
	target: self;
	selector: #saveAs;
	help: 'save the current version of the image on disk un-
	der a new name.';
	icon: Smalltalk ui icons smallSaveAsIcon.
	(aBuilder item: #'Save and quit')
	target: self;
	selector: #saveAndQuit;

help: 'save the current image on disk, and quit Pharo.'; icon: Smalltalk ui icons smallQuitIcon. ... ] StartupPreferencesLoader class >> systemStartupMenuOn: aBuilder

2016/8/12

Messages in Smalltalk are instances of the classes Message 3

2016/8/12

2016/8/12

2016/8/12

2016/8/12

2016/8/12

The full list is here: https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/ElementT 8 2016/8/12

Acknowledgements

This work was supported by Ministry of Higher Education and Research, Nord-Pas de Calais Regional Council, CPER Nord-Pas de Calais/FEDER DATA Advanced data science and technologies 2015-2020. The authors want to thank the anonymous reviewers for their excellent reviews.