My research is at the boundary of Programming Languages and Software Engineering, with particular focus on tools for improving software quality and programmer productivity. Below is an overview of some recent projects.
Refactoring is the process of applying behavior-preserving transformations to a program, in order to improve its design, and has become very popular among software developers. Together with colleagues at IBM, I have worked with the Eclipse JDT team on type-related refactorings such as Extract Interface and Infer Generic Type Arguments, which have been incorporated in the standard distribution of Eclipse. An overview of this work can be found in [TOPLAS11]. I also worked on refactorings that manipulate concurrent Java programs, by making existing refactorings safe in the presence of concurrency [ECOOP10a], making programs reentrant [FSE09], and migrating between different types of locks [ICSE11]. A [TSE 12] paper shows how type-based refactorings can be made more reliable by integrating them in a common framework that also handles issues related to name binding and accessibility.
In current object-oriented programming languages, regions of executable code are protected by locks (as implemented via, e.g., Java's synchronized blocks) to prevent concurrency-related errors such as data races or atomicity violations. Such control-centric protection of shared data requires error-prone nonlocal reasoning since the burden is on the programmer to protect all accesses to shared locations consistently. In [POPL06], we proposed atomic sets, a data-centric approach to synchronization, in which synchronization constraints are specified on data (fields in Java classes), from which the compiler automatically infers where locks need to be inserted using static program analysis. We also developed a type-based variant of this approach [ECOOP10b] that permits separate compilation. Atomic sets have an associated correctness criterion, which generalizes upon a standard notion of serializability. Violations of this criterion correspond to subtle concurrency errors, and we developed a dynamic analysis tool that found many such errors [ICSE08]. An overview of the project appeared in [TOPLAS12]. In an [ICSE13] paper, we presented a static analysis for detecting possible deadlock in AJ programs.
Several recent projects are concerned with algorithms for static program analysis. Two recent papers [ECOOP14] [TOSEM15] are concerned with type-based call graph construction algorithm for Scala. Similar to my earlier work with Jens Palsberg (see [OOPSLA00]), these algorithms only consider type information. However, they are designed to infer precise call graphs in the presence of Scala features such as traits and abstract type members. Another project is focused on performing precise interprocedural data flow analysis in the presence of correlated method calls. Our [SAS15] paper shows how an IFDS problem can be transformed into an IDE problem that avoids imprecision that arises due to correlated method calls.