Search code examples
javatypecheckingceylon

The Ceylon Typechecker: How to obtain the typed syntax tree?


Im trying to programmatically use / embed the Ceylon Typechecker to analyse Ceylon source code. In this use case I want to access all the information that normally the compiler would consume. But Im not going to compile and Im not going to add dependency on the compiler.

It seem to me that the main.Main entry point in ceylon/typechecker/src/main/Main.java is not the appropriate entry point for this use case (obtaining the typed tree and the attached models), because this information, which was collected by the visitors in the three checker passes is discarded, and only errors are printed.

So, my question is:

How can I parse and typecheck a compilation unit and then obtain 1. the typed syntax tree, and 2. the associated model objects of the types the analysis visitors encounter in the tree, which are linked to from the tree.

edited:

There was (and is) some confusion on my side about the 3 different ASTs there are.

In the README in ceylon /ceylon.ast it is said:

¨ ... ceylon.ast.core – the Ceylon classes that represent a Ceylon AST. Pure Ceylon (backend-independent). ... ceylon.ast.redhat – transforms a ceylon.ast.core AST from + to a RedHat compiler (ceylon-spec AST, and also contains functions to compile a ceylon.ast.core AST from a code string (using the RedHat compiler) ... ¨.

So there are 3 ASTs: 1. The one generated by antlr, 2. ceylon.ast.core, and 3. ceylon.ast.redhat. Why?


Solution

  • In short, you'll want to:

    • Configure a TypeCheckerBuilder with the source files you want to typecheck,
    • Obtain a TypeChecker from the builder (builder.typechecker),
    • Invoke the typechecker (typeChecker.process()),
    • Process the results available from typeChecker.phasedUnits. Specifically, typeChecker.getPhasedUnits().getPhasedUnits() will give you a List<PhasedUnit>, and for each PhasedUnit, you can call getCompilationUnit() to obtain its Tree.CompilationUnit, which is the root of the AST. AST nodes also include getters for model objects.

    For a detailed example, you can review the code for the Dart backend, working forwards and backwards from the call to process() in the compileDart() function.

    See testCompile for example code that calls compileDart().