Compiler (onionc)¶
The onionc command compiles Onion source files into JVM class files.
Usage¶
Options¶
-classpath <classpath>¶
Set the classpath for compilation. Used when your code references external Java libraries or other compiled Onion classes.
-encoding <encoding>¶
Specify the character encoding of source files. Default is platform-dependent.
-d <output directory>¶
Set the output directory for generated class files. If not specified, classes are written to the current directory.
Class files are organized by module name:
- Unix-like: org/onion_lang/MyClass.class
- Windows: org\onion_lang\MyClass.class
-maxErrorReports <count>¶
Limit the number of compilation errors reported. Useful for large projects with many errors.
--dump-ast¶
Print the parsed AST to stderr. Useful when debugging syntax and parsing.
--dump-typed-ast¶
Print a typed AST summary (classes, fields, methods) to stderr.
--profile-compile¶
Emit a compile profile with per-phase timing, source count, classpath size, and generated class count.
--profile-format <text|json>¶
Choose how the compile profile is rendered.
--profile-output <target>¶
Write the compile profile to stderr, stdout, or a file path.
onionc --profile-compile --profile-format json \
--profile-output target/profile.json \
MyProgram.on
--warn <off|on|error>¶
Control warning reporting. error treats warnings as compilation errors.
--Wno <codes>¶
Suppress specific warning categories by code or name.
Examples¶
Basic Compilation¶
Compile a single file:
This creates Hello.class in the current directory.
Multiple Files¶
Compile multiple source files:
With Output Directory¶
Organize output:
Class files appear in out/classes/.
With Classpath¶
Reference external libraries:
Complete Example¶
onionc \
-d build/classes \
-classpath lib/external.jar \
-encoding UTF-8 \
-maxErrorReports 20 \
src/*.on
Running Compiled Programs¶
After compilation, run with Java:
Or with a JAR:
# Compile
onionc -d build Main.on Helper.on
# Create JAR
jar cvfe program.jar Main -C build .
# Run JAR
java -jar program.jar
Module Organization¶
Onion uses module names (packages) similar to Java:
MyClass.on:
module com.example.myapp
class MyClass {
public:
static def main(args :String[]): void {
println("Hello")
}
}
Compile:
Output:
Run:
Compilation Errors¶
Common Errors¶
Type mismatch:
Undefined variable:
Method not found:
Incremental Compilation¶
onionc compiles all specified files each time. For large projects, consider:
- Compile only changed files
- Use a build tool (Make, SBT, Gradle)
- Organize code into modules
Build Integration¶
Makefile Example¶
SRC_DIR = src
OUT_DIR = build/classes
SOURCES = $(wildcard $(SRC_DIR)/*.on)
all: compile
compile:
mkdir -p $(OUT_DIR)
onionc -d $(OUT_DIR) $(SOURCES)
clean:
rm -rf $(OUT_DIR)
run: compile
java -cp $(OUT_DIR) Main
Shell Script Example¶
#!/bin/bash
SRC_DIR="src"
OUT_DIR="build/classes"
CLASSPATH="lib/*"
mkdir -p "$OUT_DIR"
echo "Compiling Onion sources..."
onionc -d "$OUT_DIR" -classpath "$CLASSPATH" "$SRC_DIR"/*.on
if [ $? -eq 0 ]; then
echo "Compilation successful"
echo "Running program..."
java -cp "$OUT_DIR:$CLASSPATH" Main
else
echo "Compilation failed"
exit 1
fi
Compiler Output¶
Successful Compilation¶
No output typically means success:
Compilation Errors¶
Errors are written to standard error:
$ onionc BadProgram.on
Error: Type mismatch at BadProgram.on:5
Error: Undefined variable at BadProgram.on:10
Compilation failed with 2 errors
Separate Compilation and Linking¶
Onion units can be compiled independently and linked at load time through the
classpath — you do not need all sources in one onionc invocation. Compile a
library, then compile clients against the emitted .class files.
Compile the library first:
// greeter/Greeter.on
class Greeter {
public:
def this {}
def greet(name: String): String = "Hello, " + name
}
Then compile a client against it by putting the library output on the classpath:
// app/Main.on
class Main {
public:
static def main(args: String[]): void {
IO::println((new Greeter()).greet("Onion"))
}
}
Linking is the JVM's job — run with every output directory (and onion.jar for
the runtime) on the classpath:
Classes, interfaces, records, enums, inheritance, static members and generic
types all cross unit boundaries. A generic type keeps its type parameters,
because onionc writes JVM generic signatures into the .class file:
onionc -d out/lib Container.on # class Container[T]
onionc -d out/app -classpath out/lib App.on # new Container[String](x) resolves
Compile units in dependency order (a unit must be compiled after the units it references). There is no incremental build cache — recompile a unit's dependents when its public API changes.
Next Steps¶
- Script Runner - Run Onion scripts directly
- REPL Shell - Interactive programming
- Building from Source - Build the compiler