import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;

import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

public class Test {
    public static void main(String... args) {
        try {
            new Test().run();
        } catch (Throwable t) {
            t.printStackTrace(System.err);
            System.exit(1);
        }
    }

    void run() throws IOException {
        List<JavaFileObject> files = List.of(
                createFileObject("module-info.java", "module m { }"),
                createFileObject("p/package-info.java", "/** Comment. */ package p;"),
                createFileObject("p/C.java", "package p; public class C { }")
        );

        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
        JavacTask t = (JavacTask) c.getTask(null, null, null,  null, null, files);
        Elements elements = t.getElements();
        t.addTaskListener(new TaskListener() {
            @Override
            public void started(TaskEvent e) {
                System.err.println("started: " + e);
                showTypeElement(e.getTypeElement(), elements);
            }
            @Override
            public void finished(TaskEvent e) {
                System.err.println("finished: " + e);
                showTypeElement(e.getTypeElement(), elements);
            }
        });
        t.analyze();
    }

    private void showTypeElement(TypeElement e, Elements elements) {
        if (e == null) {
            return;
        }
        
        System.err.println("type element: " + e);

        try {
            System.err.println("    module element: " + elements.getModuleOf(e));
        } catch (Throwable t) {
            System.err.println("    module element: " + t);
        }

        try {
            System.err.println("    package element: " + elements.getPackageOf(e));
        } catch (Throwable t) {
            System.err.println("    package element: " + t);
        }
    }

    private JavaFileObject createFileObject(String name, String body) {
        return createFileObject(name, JavaFileObject.Kind.SOURCE, body);
    }

    private JavaFileObject createFileObject(String name, JavaFileObject.Kind kind, String body) {
        try {
            return new SimpleJavaFileObject(new URI("myfo:///" + name), kind) {
                @Override
                public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
                    return body;
                }
            };
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException(name, e);
        }
    }
}