package com.siberika.idea.pascal.jps.compiler; import com.intellij.execution.process.ProcessAdapter; import com.intellij.openapi.util.text.StringUtil; import com.siberika.idea.pascal.jps.JpsPascalBundle; import com.siberika.idea.pascal.jps.model.JpsPascalModuleType; import com.siberika.idea.pascal.jps.util.ParamMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.PropertyKey; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Author: George Bakhtadze * Date: 15/05/2015 */ public abstract class PascalBackendCompiler { protected final CompilerMessager compilerMessager; public PascalBackendCompiler(CompilerMessager compilerMessager) { this.compilerMessager = compilerMessager; } abstract protected boolean createStartupCommandImpl(String sdkHomePath, String moduleName, String outputDirExe, String outputDirUnit, List<File> sdkFiles, List<File> moduleLibFiles, boolean isRebuild, @Nullable ParamMap pascalSdkData, ArrayList<String> commandLine); @NotNull public abstract String getId(); public abstract ProcessAdapter getCompilerProcessAdapter(CompilerMessager messager); public abstract String getCompiledUnitExt(); public String[] createStartupCommand(final String sdkHomePath, final String moduleName, final String outputDir, final List<File> sdkLibFiles, final List<File> moduleLibFiles, final List<File> files, @Nullable final ParamMap moduleData, final boolean isRebuild, @Nullable final ParamMap pascalSdkData) throws IOException, IllegalArgumentException { final ArrayList<String> commandLine = new ArrayList<String>(); if (outputDir != null) { if (!createStartupCommandImpl(sdkHomePath, moduleName, getExeOutputPath(moduleData), outputDir, sdkLibFiles, moduleLibFiles, isRebuild, pascalSdkData, commandLine)) { return null; } File mainFile = getMainFile(moduleData); if ((null == mainFile) && (files.size() > 0)) { mainFile = files.get(0); } if (mainFile != null) { commandLine.add(mainFile.getAbsolutePath()); } else { compilerMessager.error(getMessage(moduleName, "compile.noSource"), null, -1, -1); } StringBuilder sb = new StringBuilder(); for (String cmd : commandLine) { sb.append(" ").append(cmd); } compilerMessager.info(getMessage(moduleName, "compile.commandLine", sb.toString()), null, -1, -1); } else { compilerMessager.error(getMessage(moduleName, "compile.noOutputDir"), null, -1, -1); } if (commandLine.size() == 0) { throw new IllegalArgumentException(getMessage(null, "compile.errorCall")); } return commandLine.toArray(new String[commandLine.size()]); } public static File getMainFile(ParamMap moduleData) { String fileName = moduleData != null ? moduleData.get(JpsPascalModuleType.USERDATA_KEY_MAIN_FILE.toString()) : null; return fileName != null ? new File(fileName) : null; } static String getExeOutputPath(ParamMap moduleData) { return moduleData != null ? moduleData.get(JpsPascalModuleType.USERDATA_KEY_EXE_OUTPUT_PATH.toString()) : null; } protected static void addLibPathToCmdLine(final ArrayList<String> commandLine, File sourceRoot, final String compilerSettingSrcpath, final String compilerSettingIncpath) { if (sourceRoot.isDirectory()) { commandLine.add(compilerSettingSrcpath + sourceRoot.getAbsolutePath()); commandLine.add(compilerSettingIncpath + sourceRoot.getAbsolutePath()); } } protected static String getMessage(String moduleName, @PropertyKey(resourceBundle = JpsPascalBundle.JPSBUNDLE)String msgId, Object...args) { return JpsPascalBundle.message(msgId, args) + (moduleName != null ? " (" + JpsPascalBundle.message("general.module", moduleName) + ")" : ""); } protected static File checkCompilerExe(String sdkHomePath, String moduleName, CompilerMessager compilerMessager, File executable, String compilerCommand) { if (!StringUtil.isEmpty(compilerCommand)) { return checkExecutable(compilerMessager, moduleName, new File(compilerCommand)); } if (sdkHomePath != null) { return checkExecutable(compilerMessager, moduleName, executable); } else { compilerMessager.error(getMessage(moduleName, "compile.noSdkHomePath"), null, -1, -1); return null; } } private static File checkExecutable(CompilerMessager compilerMessager, String moduleName, File executable) { if (executable.exists() && executable.canExecute()) { return executable; } else { compilerMessager.error(getMessage(moduleName, "compile.noCompiler", executable.getPath()), null, -1, -1); return null; } } }