Type Errors for the IDE with Xtext and Xsemantics Perience and Contributes to the Adoption of That Language
Total Page:16
File Type:pdf, Size:1020Kb
Open Comput. Sci. 2019; 9:52–79 Research Article Open Access Lorenzo Bettini* Type errors for the IDE with Xtext and Xsemantics https://doi.org/10.1515/comp-2019-0003 perience and contributes to the adoption of that language. Received June 29, 2018; accepted February 11, 2019 However, developing a compiler and an IDE for a language from scratch is usually time consuming. Language work- Abstract: Providing IDE support for a programming lan- benches, a term coined by Martin Fowler in 2005 [1], are guage or a DSL (Domain Specific Language) helps the users software development tools designed to easily implement of the language to be more productive and to have an im- languages together with their IDE support. Xtext [2] is one mediate feedback on possible errors in a program. Static of the most popular language workbench. Starting from a types can drive IDE mechanisms such as the content as- grammar definition Xtext generates a parser, an abstract sist to propose sensible completions in a given program syntax tree (AST), and typical IDE mechanisms. While the context. Types can also be used to enrich other typical IDE main target of Xtext is Eclipse, a language developed with parts such as the Outline and the Hovering pop-ups. In this Xtext can be easily ported to other IDEs and editors. Xtext paper, we focus on statically typed imperative languages, comes with good defaults for all the above artifacts, di- adopting some form of type inference. We present a few rectly inferred from the grammar definition, and the lan- general patterns for implementing efficient type systems, guage developer can easily customize them all. focusing on type error recovery. This way, the type system Statically typed languages provide good IDE support. is able to type as many parts of the program as possible, Indeed, given an expression and its static type, the editor keeping a good IDE experience. Type error messages will can provide useful completion proposals that make sense be placed on the important parts of the program, avoid- in that program context. The same holds for other typical ing cascading errors that can confuse the user. We show IDE features, e.g., navigation to declaration, hovering and two case studies: we apply the presented patterns to imple- outline. In spite of the ease of implementing a language ment the type system of two statically typed DSLs, a sim- and its IDE support with a language workbench like Xtext, ple expression language and a reduced Java-like language, the implementation of the type system requires some effort with OOP features. We use Xtext as the language work- and careful tweaking: bench for implementing the compiler and the IDE sup- – The type system should type as many parts of a pro- port and Xsemantics, a DSL for implementing type systems gram as possible, so that the IDE can provide mean- using a syntax that mimics formal systems. The patterns ingful code completions even in the presence of an in- shown in the paper can be reused also for implementing complete and invalid program. languages with other language frameworks. – Type error messages should be placed on the impor- Keywords: language implementation, type system, IDE tant parts of the program, helping the user to quickly understand and fix the errors, avoiding cascading er- rors that would only confuse the user. 1 Introduction – Type computation should be performed quickly, in or- der to keep the IDE responsive. Integrated Development Environments (IDEs) help pro- In this paper we concentrate on mechanisms related to the grammers with mechanisms like syntax aware editor (syn- implementation of type systems addressing the above is- tax highlighting), immediate error reporting, code comple- sues, focusing on type errors and IDE support. The contri- tion (also known as content assist) and easy navigation butions of the paper are: to declarations. Providing IDE support for a language or – We describe some general implementation patterns a DSL (Domain Specific Language) enhances the user ex- for implementing type systems that aim at reporting only the important errors, with useful error messages, keeping the IDE responsive. In particular, we concen- *Corresponding Author: Lorenzo Bettini: Dipartimento di Statis- trate on imperative languages, adopting some form of tica, Informatica, Applicazioni, Università di Firenze, Italy; type inference. E-mail: [email protected] Open Access. © 2019 Lorenzo Bettini, published by De Gruyter. This work is licensed under the Creative Commons Attribution alone 4.0 License Type errors for the IDE with Xtext and Xsemantics Ë 53 – We then demonstrate the benefits of such patterns first case study, showing the implementation of thetype by implementing two example DSLs in Xtext: a sim- system for the Expressions DSL. Section 5 shows our sec- ple “Expressions DSL” (with arithmetic, string and ond case study, that is, the implementation of the type boolean expressions) and a reduced version of Java, system of an OO language, Featherweight Java. Section 6 based on Featherweight Java (FJ) [3], a well-known for- discusses further improvements to the type system imple- mal framework for studying properties of the Java lan- mentations of the two DSLs. Section 7 discusses a few re- guage and for introducing extensions to Java. lated works. Section 8 concludes the paper. – For both examples, we show the benefits of applying the described patterns, in terms of the user experi- ence. 2 General implementation patterns Both languages¹ are simple languages but their type sys- A crucial issue to keep in mind when implementing type tems are complex enough to help us investigate best prac- systems is error recovery. This is similar to error recovery in tices in type system implementation. We implement the parser implementations [5]: a parser should be able to han- type system of the first DSL manually, while for FJ we use dle possible parsing errors and carry on parsing as much Xsemantics [4], a DSL for implementing type systems for of the rest of the input as possible, avoiding or minimizing Xtext languages. Xsemantics provides many features for additional cascading errors. The same holds for the type implementing complex type systems, like the one of FJ (in system: it should be able to type and check as many parts spite of its simplicity, the type system of FJ formalizes the of a program as possible, even in the presence of type er- main parts of the Java type system). Moreover, Xsemantics rors. Thus, the type system should avoid throwing cascad- provides a syntax that is close to formal type systems and ing errors due to previously failed type computations. This this makes it suitable to implement type systems that have is important in a command line compiler, but in the IDE it been formalized, like FJ’s type system [3]. The syntax of is even more crucial: we should minimize the portions of the two example DSLs is partly inspired by our previous the edited file marked with errors. This way, the user can work [2, 4], but the implementations shown in this paper easily understand the errors and quickly fix them. In par- are new. ticular, the type system will be continuously used by the The patterns presented in the paper are not strictly de- IDE while the user is editing the program. Thus, the pro- pendent on Xtext, Xsemantics and Eclipse: these are the gram that is examined by the type system will be an in- frameworks that are used in the paper to present our case complete program most of the time. studies. The same patterns could be applied to other lan- In this section we present some general implementa- guage workbenches. The basic idea of the implementation tion patterns for implementing type systems that aim at patterns will be given independently from these frame- reporting only the important errors, with useful messages works. and at providing a good user experience in the IDE. The intended audience of the paper is developers of We consider the implementation of a type system as statically typed languages and DSLs with IDE support. In the synergy of two main components: the type inference, particular, we will use Xtext as the language workbench that is, the mechanism responsible of computing the types and Eclipse as the target IDE. A basic knowledge of lan- of the program elements, and the type checker, that is, the guage implementation and type systems is advisable. We mechanism responsible of validating the program with re- will provide enough details on Xtext in order to make the spect to types. These two components will also have to co- examples understandable even by readers who are not fa- operate with the mechanism for cross reference resolution. miliar with Xtext. The paper is structured as follows. Section 2 motivates Infer a type as quickly as possible. Given a compos- our work and presents our general implementation pat- ite expression, if its type can be computed independently terns for type systems. Section 3 provides a brief introduc- from its subexpressions, the subexpressions should not tion to Xtext and its main mechanisms using the Expres- be inspected recursively. This has the benefit of improv- sions DSL as a running example. Section 4 illustrates our ing error recovery and the type inference performance. For example, let us consider an arithmetic expression of the shape e1 * e2². We can infer that the type of the expres- 1 The source code of the implemented DSLs presented in this pa- per can be found at: https://github.com/LorenzoBettini/xtext-type- errors-examples. 2 Where * is assumed to be the standard multiplication operator. 54 Ë Lorenzo Bettini sion is numeric, independently from the types of subex- pression will not be marked with an error.