Class FileConstructOutputSink

java.lang.Object
org.ek9lang.compiler.backend.FileConstructOutputSink
All Implemented Interfaces:
ConstructOutputSink

public final class FileConstructOutputSink extends Object implements ConstructOutputSink
Writes each generated class to its own file - the behaviour every jvm writer had inline.

This is the DEFAULT sink, and deliberately so: everything that reads the exploded output rather than the jar depends on it - the -t test runner, the REPL (ReplCompiler hands back a bytecode directory), the IDE, and the bytecode test harnesses. A caller opts in to holding bytes only when it knows the jar is the sole consumer.

Thread-safe: each call writes a distinct file, and makeDirectoryIfNotExists is idempotent and (since the OsSupport change) lock-free.

  • Constructor Details

    • FileConstructOutputSink

      public FileConstructOutputSink()
  • Method Details

    • write

      public void write(File target, byte[] content)
      Description copied from interface: ConstructOutputSink
      Accept one generated class.
      Specified by:
      write in interface ConstructOutputSink
      Parameters:
      target - the file this class WOULD occupy. It is the identity of the output, not necessarily a path that gets written: a jar sink relativises it to an entry name, an in-memory sink uses it as a key. Keeping it a File means the naming stays identical to the pre-sink pipeline, which is what makes byte-identical output verifiable.
      content - the class bytes.
    • read

      public Optional<byte[]> read(File target)
      Description copied from interface: ConstructOutputSink
      Read back a class this sink was given, if it has it.

      This exists because the sink is the single source of generated bytes, and something inside the compile needs to read them back: ByteCodeDirectiveListener validates @BYTECODE directives during compilation and used to go straight to the filesystem. That is correct only while the bytes are on the filesystem, so it would fail - loudly, but for a confusing reason - the moment a caller chose a sink that holds them. Asking the sink removes the question rather than documenting it.

      Specified by:
      read in interface ConstructOutputSink
      Parameters:
      target - the same file identity that was passed to ConstructOutputSink.write(File, byte[]).
      Returns:
      the bytes, or empty if this sink does not have them.