Search code examples
moduletypecheckingceylon

Running the ceylon typechecker from ceylon, like in typechecker/src/main/Main.java


I'm running the ceylon typechecker from a ceylon project with a run.ceylon which is exactly a ceylon version of typechecker/src/main/Main.java.

This project is supposed to typecheck itself.

It compiles without errors, but at runtime cannot load dependencies for typechecking.

file: source/com/example/withmodule/module.ceylon

native("jvm")
module com.example.withmodule "1.0" {
    import com.redhat.ceylon.typechecker "1.3.0" ;
    //import     com.redhat.ceylon.module-resolver "1.3.0";
}

file: source/com/example/withmodule/run.ceylon

import java.io{File}
import com.redhat.ceylon.cmr.api{RepositoryManager}
import com.redhat.ceylon.cmr.ceylon{CeylonUtils}
import com.redhat.ceylon.compiler.typechecker{TypeCheckerBuilder}
import com.redhat.ceylon.compiler.typechecker.io.cmr.impl{LeakingLogger}

shared void run(){

   value args = ["/absolutepath/ceylon-1.3.0/source/"];


    RepositoryManager repositoryManager = 
            CeylonUtils.repoManager()
                .systemRepo("/absolutepath/ceylon-1.3.0/repo")
                .logger( LeakingLogger())
                .buildManager();

    TypeCheckerBuilder tcb = 
              TypeCheckerBuilder()
                .setRepositoryManager(repositoryManager)
                .verbose(true)
                .statistics(true);

    for (String path in args) {
        tcb.addSrcDirectory( File(path));
    }

    tcb.typeChecker.process();
}

It compiles without errors.

But when running it produces errors:

error [package not found in imported modules: 'com.redhat.ceylon.cmr.api' (add module import to module descriptor of 'com.example.withmodule')] at 2:7-2:31 of com/example/withmodule/withmodule.ceylon
error [package not found in imported modules: 'com.redhat.ceylon.cmr.ceylon' (add module import to module descriptor of 'com.example.withmodule')] at 3:7-3:34 of com/example/withmodule/withmodule.ceylon
error [package not found in imported modules: 'com.redhat.ceylon.compiler.typechecker' (add module import to module descriptor of 'com.example.withmodule')] at 4:7-4:44 of com/example/withmodule/withmodule.ceylon
error [package not found in imported modules: 'com.redhat.ceylon.compiler.typechecker.io.cmr.impl' (add module import to module descriptor of 'com.example.withmodule')] at 5:7-5:56 of com/example/withmodule/withmodule.ceylon

This makes no sense to me, because compilation and typechecking had succeded just before.

It's a fresh ceylon 1.3.0 download, not installed, simply run from the unzipped .tar.gz.

What extra information does the typechecker need that it hadn't got?


Solution

  • So the issue here is that the typechecker we use in the test runner typechecker/src/main/Main.java is only able to understand things defined in Ceylon source code. It is not able to read a compiled Java .jar archive and typecheck your Ceylon source code against the classes in that archive.

    So to be able to typecheck Ceylon code that depends on Java binaries, you would need more infrastructure, including what we call a "model loader" which is responsible for building a Ceylonic model of the Java binary .classes. There are a number different model loaders in the Ceylon ecosystem—one for javac, one for Eclipse, one for IntelliJ, one that uses Java reflection, one for Dart, one for typescript, one for JS—and they're all very specific to a particular compilation environment.

    So the tests for the Ceylon typechecker, which don't depend on javac, IntelliJ, Eclipse, etc, etc, don't feature any sort of Java interop. Your code can successfully typecheck things defined in Ceylon source code, including code that depends on Ceylon modules with .src archives produced by the Ceylon compiler, but it can't typecheck things defined in a Java .jar archive.

    I hope that helps.