Network


Latest external collaboration on country level. Dive into details by clicking on the dots.

Hotspot


Dive into the research topics where Max Schäfer is active.

Publication


Featured researches published by Max Schäfer.


conference on object-oriented programming systems, languages, and applications | 2008

Sound and extensible renaming for java

Max Schäfer; Torbjörn Ekman; Oege de Moor

Descriptive names are crucial to understand code. However, good names are notoriously hard to choose and manually changing a globally visible name can be a maintenance nightmare. Hence, tool support for automated renaming is an essential aid for developers and widely supported by popular development environments. This work improves on two limitations in current refactoring tools: too weak preconditions that lead to unsoundness where names do not bind to the correct declarations after renaming, and too strong preconditions that prevent renaming of certain programs. We identify two main reasons for unsoundness: complex name lookup rules make it hard to define sufficient preconditions, and new language features require additional preconditions. We alleviate both problems by presenting a novel extensible technique for creating symbolic names that are guaranteed to bind to a desired entity in a particular context by inverting lookup functions. The inverted lookup functions can then be tailored to create qualified names where otherwise a conflict would occur, allowing the refactoring to proceed and improve on the problem with too strong preconditions. We have implemented renaming for Java as an extension to the JastAdd Extensible Java Compiler and integrated it in Eclipse. We show examples for which other refactoring engines have too weak preconditions, as well as examples where our approach succeeds in renaming entities by inserting qualifications. To validate the extensibility of the approach we have implemented renaming support for Java 5 and AspectJ like inter-type declarations as modular extensions to the initial Java 1.4 refactoring engine. The renaming engine is only a few thousand lines of code including extensions and performance is on par with industrial strength refactoring tools.


european conference on object oriented programming | 2009

Stepping Stones over the Refactoring Rubicon

Max Schäfer; Mathieu Verbaere; Torbjörn Ekman; Oege de Moor

Refactoring tools allow the programmer to pretend they are working with a richer language where the behaviour of a program is automatically preserved during restructuring. In this paper we show that this metaphor of an extended language yields a very general and useful implementation technique for refactorings: a refactoring is implemented by embedding the source program into an extended language on which the refactoring operations are easier to perform, and then translating the refactored program back into the original language. Using the well-known Extract Method refactoring as an example, we show that this approach allows a very fine-grained decomposition of the overall refactoring into a series of micro-refactorings that can be understood, implemented, and tested independently. We thus can easily write implementations of complex refactorings that rival and even outperform industrial strength refactoring tools in terms of correctness, but are much shorter and easier to understand.


international conference on software engineering | 2011

Refactoring Java programs for flexible locking

Max Schäfer; Manu Sridharan; Julian Dolby; Frank Tip

Recent versions of the Java standard library offer flexible locking constructs that go beyond the languages built-in monitor locks in terms of features, and that can be fine-tuned to suit specific application scenarios. Under certain conditions, the use of these constructs can improve performance significantly, by reducing lock contention. However, the code transformations needed to convert between locking constructs are non-trivial, and great care must be taken to update lock usage throughout the program consistently. We present Relocker, an automated tool that assists programmers with refactoring synchronized blocks into ReentrantLocks and ReadWriteLocks, to make exploring the performance tradeoffs among these constructs easier. In experiments on a collection of real-world Java applications, Relocker was able to refactor over 80% of built-in monitors into ReentrantLocks. Additionally, in most cases the tool could automatically infer the same ReadWriteLock usage that programmers had previously introduced manually.


conference on object-oriented programming systems, languages, and applications | 2011

Tool-supported refactoring for JavaScript

Asger Feldthaus; Todd D. Millstein; Anders Møller; Max Schäfer; Frank Tip

Refactoring is a popular technique for improving the structure of existing programs while maintaining their behavior. For statically typed programming languages such as Java, a wide variety of refactorings have been described, and tool support for performing refactorings and ensuring their correctness is widely available in modern IDEs. For the JavaScript programming language, however, existing refactoring tools are less mature and often unable to ensure that program behavior is preserved. Refactoring algorithms that have been developed for statically typed languages are not applicable to JavaScript because of its dynamic nature. We propose a framework for specifying and implementing JavaScript refactorings based on pointer analysis. We describe novel refactorings motivated by best practice recommendations for JavaScript programming, and demonstrate how they can be described concisely in terms of queries provided by our framework. Experiments performed with a prototype implementation on a suite of existing applications show that our approach is well-suited for developing practical refactoring tools for JavaScript.


european conference on object oriented programming | 2010

Correct refactoring of concurrent java code

Max Schäfer; Julian Dolby; Manu Sridharan; Emina Torlak; Frank Tip

Automated refactorings as implemented in modern IDEs for Java usually make no special provisions for concurrent code. Thus, refactored programsmay exhibit unexpected new concurrent behaviors.We analyze the types of such behavioral changes caused by current refactoring engines and develop techniques tomake thembehavior-preserving, ranging from simple techniques to deal with concurrency-related language constructs to a framework that computes and tracks synchronization dependencies. By basing our development directly on the JavaMemoryModel, we can state and prove precise correctness results about refactoring concurrent programs. We show that a broad range of refactorings are not influenced by concurrency at all, whereas other important refactorings can be made behavior-preserving for correctly synchronized programs by using our framework. Experience with a prototype implementation shows that our techniques are easy to implement and require only minimal changes to existing refactoring engines.


programming languages meets program verification | 2009

Challenge proposal: verification of refactorings

Max Schäfer; Torbjörn Ekman; Oege de Moor

Automated refactoring tools are an essential part of a software developers toolbox. They are most useful for gradually improving large existing code bases and it is essential that they work reliably, since even a simple refactoring may affect many different parts of a program, and the programmer should not have to inspect every individual change to ensure that the transformation went as expected. Even extensively tested industrial-strength refactoring engines, however, are fraught with many bugs that lead to incorrect, non-behaviour preserving transformations. We argue that software refactoring tools are a prime candidate for mechanical verification, offering significant challenges but also the prospect of tangible benefits for real-world software development.


symposium on principles of programming languages | 2010

Type inference for datalog with complex type hierarchies

Max Schäfer; Oege de Moor

Type inference for Datalog can be understood as the problem of mapping programs to a sublanguage for which containment is decidable. To wit, given a program in Datalog, a schema describing the types of extensional relations, and a user-supplied set of facts about the basic types (stating conditions such as disjointness, implication or equivalence), we aim to infer an over-approximation of the semantics of the program, which should be expressible in a suitable sublanguage of Datalog. We argue that Datalog with monadic extensionals is an appropriate choice for that sublanguage of types, and we present an inference algorithm. The inference algorithm is proved sound, and we also show that it infers the tightest possible over-approximation for a large class of Datalog programs. Furthermore, we present a practical containment check for a large subset of our type language. The crux of that containment check is a novel generalisation of Quines procedure for computing prime implicants. The type system has been implemented in a state-of-the-art industrial database system, and we report on experiments with this implementation.


conference on object oriented programming systems languages and applications | 2008

Refactoring is not (yet) about transformation

Torbjörn Ekman; Max Schäfer; Mathieu Verbaere

In order to ensure correctness, refactorings have to check extensive preconditions before performing the transformation. These preconditions usually involve subtle analyses of the program to be refactored, and as long as there is no good support for implementing them, refactoring is not about transformation, but about analysis. In most cases, these refactoring analyses are very similar to analyses implemented in a compiler and require the same level of detail to ensure behaviour preservation. We therefore propose to implement a refactoring engine on top of a compiler to leverage existing infrastructure, and complement it with refactoring-specific functionality. Many simple refactorings appear as building blocks in more complex refactorings. We have implemented two such building blocks that are widely useful: The first one allows to move symbolic names from one place in the program to another while preserving binding structure; it frees the developer from having to worry about issues like name clashes and accidental overriding. The second building block encapsulates data flow and control flow analyses, enabling the developer to specify precise conditions for validity of a transformation in terms of concepts like dominance and liveness. Based on these approaches, we have implemented a refactoring engine as part of a larger effort to generate IDEs from declarative language specifications using the JastAdd metacompiler tools. The described building blocks were successfully used as a foundation for other refactorings such as Rename, Extract Method, and Encapsulate Field.


european conference on object-oriented programming | 2016

QL: Object-oriented Queries on Relational Data.

Pavel Avgustinov; Oege de Moor; Michael Peyton Jones; Max Schäfer

This paper describes QL, a language for querying complex, potentially recursive data structures. QL compiles to Datalog and runs on a standard relational database, yet it provides familiar-looking object-oriented features such as classes and methods, reinterpreted in logical terms: classes are logical properties describing sets of values, subclassing is implication, and virtual calls are dispatched dynamically by considering the most specific classes containing the receiver. Furthermore, types in QL are prescriptive and actively influence program evaluation rather than just describing it. In combination, these features enable the development of concise queries based on reusable libraries, which are written in a purely declarative style, yet can be efficiently executed even on very large data sets. In particular, we have used QL to implement static analyses for various programming languages, which scale to millions of lines of code.


european symposium on programming | 2009

Formalising and Verifying Reference Attribute Grammars in Coq

Max Schäfer; Torbjörn Ekman; Oege de Moor

Reference attribute grammars are a powerful formalism for concisely specifying and implementing static analyses. While they have proven their merit in practical applications, no attempt has so far been made to rigorously verify correctness properties of the resulting systems. We present a general method for formalising reference attribute grammars in the theorem prover Coq. The formalisation is supported by tools for generating standard definitions from an abstract description and custom proof tactics to help automate verification. As a small but typical application, we show how closure analysis for the untyped lambda calculus can easily be implemented and proved correct with respect to an operational semantics. To evaluate the feasibility of our approach on larger systems, we implement name lookup for a naming core calculus of Java and give a formal correctness proof of the centrepiece of a rename refactoring for this language.

Collaboration


Dive into the Max Schäfer's collaboration.

Top Co-Authors

Avatar
Top Co-Authors

Avatar
Top Co-Authors

Avatar
Top Co-Authors

Avatar
Top Co-Authors

Avatar
Top Co-Authors

Avatar
Top Co-Authors

Avatar
Researchain Logo
Decentralizing Knowledge