package scotch.runner;
import static java.lang.System.err;
import static java.lang.System.exit;
import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import scotch.compiler.ClassLoaderResolver;
import scotch.compiler.PathCompiler;
import scotch.compiler.error.CompileException;
import scotch.symbol.SymbolResolver;
public class CompilerRunner {
public static void main(String[] args) throws ParseException, IOException {
Options options = createOptions();
try {
run(args, options);
} catch (CompileException exception) {
exception.printErrors();
exit(1);
} catch (IOException | RuntimeException exception) {
err.println(exception.getMessage());
exit(1);
} catch (ParseException exception) {
showHelp(options);
}
}
private static Options createOptions() {
Options options = new Options();
options.addOption(new Option("cp", "Specifies the classpath to use during compilation") {{
setLongOpt("classpath");
setRequired(false);
setArgs(1);
}});
options.addOption(new Option("o", "Specifies the output path for compiled classes") {{
setLongOpt("output-path");
setRequired(false);
setArgs(1);
}});
options.addOption(new Option("h", "Shows this help") {{
setLongOpt("help");
setRequired(false);
setArgs(0);
}});
return options;
}
private static List<URL> getClasspath(CommandLine cli) {
List<URL> classpath;
if (cli.hasOption("cp") || cli.hasOption("classpath")) {
classpath = stream(cli.getOptionValue("cp", cli.getOptionValue("classpath", "")).split(File.pathSeparator))
.map(path -> {
try {
return new File(path).getAbsoluteFile().toURI().toURL();
} catch (MalformedURLException exception) {
throw new RuntimeException(exception);
}
})
.collect(toList());
} else {
classpath = emptyList();
}
return classpath;
}
private static void run(String[] args, Options options) throws ParseException, IOException {
CommandLineParser parser = new GnuParser();
CommandLine cli = parser.parse(options, args);
if (cli.hasOption("h") || cli.hasOption("help")) {
showHelp(options);
return;
}
List<URL> classpath = getClasspath(cli);
File outputPath = new File(cli.getOptionValue("o", cli.getOptionValue("output-path", "build")));
List<File> inputFiles = stream(cli.getArgs()).map(File::new).collect(toList());
SymbolResolver symbolResolver = new ClassLoaderResolver(
Optional.empty(),
classpath.toArray(new URL[classpath.size()]),
CompilerRunner.class.getClassLoader()
);
new PathCompiler(symbolResolver, outputPath, inputFiles).compile();
}
private static void showHelp(Options options) {
new HelpFormatter().printHelp("sc [-o output path] [-cp classpath] file1 [file2 [fileN...]]", options);
}
}