Reflection Analysis and First Steps in Its Control
Reflection Analysis and First Steps in Its Control
Résumé
Reflective operations are powerful APIs (Application Programming Interfaces) that
enable developers to build advanced tools and architectures. Reflective operations
are used to implement tools and development environments (e.g. compilers, de-
buggers, inspectors) and language features (e.g. distributed systems, exceptions,
proxies).
Programming languages evolve, introducing better concepts, and revising prac-
tices and APIs. For example, since 2008, Pharo has evolved from Squeak and
its reflective API has evolved accordingly, diverging from the original Smalltalk
reflective API. Pharo has a large set of over 500 reflective methods, often built on top
of each other. They range from structural reflection to on-demand stack reification.
This thesis describes 3 main works:
• Inventory and classification of reflective operations,
• Assessing dependencies to reflection with mutation analysis,
• Protected visibility modifiers and applicability to reflective infrastructures.
Inventory and classification of reflective operations: Understanding such
APIs is tedious. There is a need for a deep analysis of current reflective APIs to
understand their underlying use, potential dependencies, and whether some reflective
features can be scoped and made optional. Such an analysis is challenged by new
metaobjects introduced into the system, such as first-class instance variables, and
their mixture with the base-level API.
We propose an inventory and a classification of these operations based on their
semantics. We also identify a set of issues of the current implementation and analyze
their inter-dependencies. Such an analysis of reflective operations is important to
support the rational evolution of the reflective layer and its potential redesign.
Assessing dependencies to reflection with mutation analysis: While reflection
is a powerful tool, developers may use it to circumvent data encapsulation and
method visibility modifiers. Thus, it is important to assess the extent to which an
application relies on reflection. Nonetheless, reflection is mostly incompatible with
static analysis as it relies on runtime information. These problems are exacerbated
in dynamically-typed languages, where reflective operations are polymorphic with
non-reflective ones.
To this end, we present RAPIM, an approach to assess the uses of reflective
APIs: it uses mutation analysis with a new mutation operator to handle core reflec-
tive methods. We compare the performance of our approach against static analysis
on a selection of 5 projects. On four out of five projects, RAPIM disambiguates
more potentially reflective call-sites than static analysis. When code coverage is
high, the percentage of disambiguation is three times higher. Finally, we question
the relevance of polymorphism between non-reflective and reflective APIs.
Protected visibility modifiers and applicability to reflective infrastructures:
In our exploration of means to control reflection, we examined method visibility
to separate internal methods from the public API. Protected visibility modifiers
provide a way to hide methods from external objects while authorizing internal
use and overriding in subclasses. While present in main statically-typed languages,
visibility modifiers are not as common or mature in dynamically-typed languages.
In Pharo, all methods are public. While only a few reflective methods could be
protected due to their uses, many reflective metaobjects could benefit from having a
protected modifier for internal methods.
We present PROTDYN, a visibility model for dynamically-typed languages that
is computed at compile time. It relies on name-mangling and syntactic differ-
entiation between self vs non-self-sends. Its Pharo implementation is backward
compatible with existing programs. We study its performance, memory footprint,
and compatibility with existing optimizations to demonstrate its viability.
While this thesis focuses on Pharo, the results can be applied to many dynamically-
typed languages.
Les opérations réflexives sont des API (interfaces de programmation d’applications)
qui permettent aux developpeur·euse·s de construire des outils avancés et de modifier
l’architecture d’un langage. Elles permettent de créer des outils pour les environ-
nements de développement (compilateurs, débogueurs, inspecteurs) ou de concevoir
de nouvelles fonctionnalités dans un langage (systèmes distribués, exceptions, prox-
ies).
Les langages de programmation évoluent, introduisant de meilleurs concepts
et mettant à jour les pratiques et les API. À l’origine proche de Squeak, Pharo a
évolué depuis 2008 et ses API réflexives ont divergé de celles d’origine de Smalltalk.
Avec plus de 500 méthodes réflexives identifiées, Pharo possède un large panel de
fonctionnalités réflexives.
Cette thèse présente trois travaux principaux :
• Un inventaire et une classification des opérations réflexives;
• Analyser les dépendances à la réflexion;
• Les modificateurs de visibilité et leur applicabilité aux infrastructures réflex-
ives;
Inventaire et classification : Il est nécessaire d’analyser les API réflexives
actuelles afin de comprendre leurs usages, leurs dépendances et si certaines pour-
raient être limitées ou optionnelles. Cette analyse est rendue complexe par l’ajout
de nouveaux métaobjets dans Pharo, tels que les variables d’instance de première
classe et par leur mélange avec les API non-réflexives.
Nous proposons un inventaire et une classification sémantique de ces opéra-
tions réflexives. Nous analysons leurs interdépendances et identifions un ensemble
de problèmes liés à l’implémentation actuelle. Cette analyse pourra informer les
prochaines évolutions de la couche réflexive.
Analyser la dépendance à la réflexion: La réflexion est un outil puissant qui
peut contourner l’encapsulation des données et les modificateurs de visibilité. Il
est donc important de pouvoir évaluer dans quelle mesure une application repose
sur la réflexion. Puisque la réflexion dépend d’informations dynamiques, l’analyse
statique est limitée. Ces problèmes sont accrus dans les langages dynamiquement
typés en raison du polymorphisme.
Nous proposons donc RAPIM, une approche pour évaluer l’utilisation de la
réflexion. Celle-ci utilise l’analyse de mutation avec un nouvel opérateur de mutation
pour traiter les méthodes réflexives du noyau. Nous comparons les performances
de notre approche à celles de l’analyse statique sur une sélection de cinq projets.
Pour quatre projets, RAPIM désambiguïse plus d’appels potentiellement réflexifs
que l’analyse statique. Lorsque la couverture du code est élevée, le pourcentage de
désambiguïsassions est trois fois plus élevé. Enfin, nous questionnons la pertinence
du polymorphisme entre les API réflexives et non-réflexives.
Modificateurs de visibilité: Dans notre exploration des moyens de contrôler la
réflexion, nous avons examiné la visibilité des méthodes pour séparer les méthodes
internes de l’API publique. Les modificateurs de visibilité (protected) permettent
de cacher les méthodes aux objets externes tout en autorisant l’utilisation interne et
la surcharge dans les sous-classes. Bien qu’ils soient présents dans les principaux
langages statiquement typés, ce type de modificateur n’est pas aussi courant ou
mature dans les langages dynamiquement typés. En Pharo, toutes les méthodes
sont publiques. Bien que peu de méthodes réflexives puissent être protégées en
raison de leur utilisation, de nombreux métaobjets réflexifs bénéficieraient d’un
modificateur pour les méthodes internes. Nous présentons PROTDYN, un modèle de
visibilité pour les langages dynamiques calculé à la compilation et s’appuyant sur la
distinction syntaxique de l’usage (ou non) de self. Son implémentation Pharo est
rétro-compatible. Nous évaluons ses performances, son utilisation de la mémoire et
sa compatibilité avec les optimisations existantes.
Bien que cette thèse se concentre sur Pharo, les résultats peuvent être appliqués
à d’autres langages dynamiquement typés.
Origine | Fichiers produits par l'(les) auteur(s) |
---|---|
licence |
Domaine public
|