package org.dlangplugin.run; import com.intellij.execution.ExecutionException; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.CompilerModuleExtension; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import org.dlangplugin.run.exception.NoSourcesException; import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.LinkedList; import java.util.List; /** Static class to convert all properties of DLangRunDmdConfiguration to DMD command line arguments. * @see http://dlang.org/dmd-linux.html#switches */ public class DLangDmdConfigToArgsConverter { public static List<String> getDmdParameters(DLangRunDmdConfiguration config, Module module) throws NoSourcesException, ExecutionException { VirtualFile sourcesRoot = getSourceRoot(module); VirtualFile[] excludedRoots = getExcludedRoots(module); List<String> dmdParameters = new LinkedList<String>(); dmdParameters.addAll(configToParameters(config)); dmdParameters.add(getOutputPathArgument(module)); dmdParameters.add(getOutputFileArgument(module, config)); dmdParameters.addAll(getAllDLangSources(sourcesRoot, excludedRoots)); return dmdParameters; } private static VirtualFile getSourceRoot(Module module) { if (module != null) { VirtualFile[] sourcesRoots = ModuleRootManager.getInstance(module).getSourceRoots(); if (sourcesRoots.length >= 1) { return sourcesRoots[0]; } } return null; } private static VirtualFile[] getExcludedRoots(Module module) { if (module != null) { return ModuleRootManager.getInstance(module).getExcludeRoots(); } return null; } @NotNull private static String getOutputPathArgument(Module module) { String outputDirUrl = getOutputDir(module); File outputDir = new File(VfsUtilCore.urlToPath(outputDirUrl), "obj"); return "-od"+outputDir.getPath(); } @NotNull private static String getOutputFileArgument(Module module, DLangRunDmdConfiguration config) { return "-of"+getOutputFilePath(module, config); } @NotNull private static String getOutputFilePath(Module module, DLangRunDmdConfiguration config) { String filename = module.getName(); if(config.isLibrary()) { filename += ".lib"; } else if(SystemInfo.isWindows) { filename += ".exe"; } String outputDirUrl = getOutputDir(module); File outputFile = new File(VfsUtilCore.urlToPath(outputDirUrl), filename); return outputFile.getPath(); } private static String getOutputDir(Module module) { return ModuleRootManager.getInstance(module).getModuleExtension(CompilerModuleExtension.class).getCompilerOutputUrl(); } private static List<String> configToParameters(DLangRunDmdConfiguration config) { LinkedList<String> result = new LinkedList<String>(); buildCompilerParameters(config, result); buildOutputParameters(config, result); buildDebugParameters(config, result); return result; } private static void buildCompilerParameters(DLangRunDmdConfiguration config, List<String> parameters) { if(config.isRelease()) { parameters.add("-release"); } if(config.isDebug()) { parameters.add("-debug"); } if(config.isUnitTest()) { parameters.add("-unittest"); } if(config.isLink()) { parameters.add("-link"); } if(config.isCoverageAnalysis()) { parameters.add("-cov"); } if(config.isAllowDeprecated()) { parameters.add("-d"); } if(config.isIgnorePragmas()) { parameters.add("-ignore"); } if(config.isFunctionInlining()) { parameters.add("-inline"); } if(config.isLibrary()) { parameters.add("-lib"); } if(config.isNoArrayBoundsCheck()) { parameters.add("-noboundscheck"); } if(config.isNoFloatingPointReferences()) { parameters.add("-nofloat"); } if(config.isOptimize()) { parameters.add("-O"); } if(config.isEnforcePropertySyntax()) { parameters.add("-property"); } if(config.isQuiet()) { parameters.add("-quiet"); } if(config.isVerbose()) { parameters.add("-v"); } if(config.isListThreadLocalStorage()) { parameters.add("-vtls"); } if(config.isWarnings()) { parameters.add("-w"); } if(config.isInfoWarnings()) { parameters.add("-wi"); } if ( !StringUtil.isEmptyOrSpaces(config.getDefaultLibrary()) ) { parameters.add("-defaultlib=" + config.getDefaultLibrary()); } if ( !StringUtil.isEmptyOrSpaces(config.getImportsPath()) ) { parameters.add("-I" + config.getImportsPath()); } if ( !StringUtil.isEmptyOrSpaces(config.getStringImportsPath()) ) { parameters.add("-J" + config.getStringImportsPath()); } if ( !StringUtil.isEmptyOrSpaces(config.getLinkerArgs()) ) { parameters.add("-L" + config.getLinkerArgs()); } } private static void buildOutputParameters(DLangRunDmdConfiguration config, List<String> parameters) { if(config.isGenerateDocs()) { parameters.add("-D"); if( !StringUtil.isEmptyOrSpaces(config.getDocsPath())) { parameters.add("-Dd"+config.getDocsPath()); } if( !StringUtil.isEmptyOrSpaces(config.getDocsFilename())) { parameters.add("-Df"+config.getDocsFilename()); } } if( !StringUtil.isEmptyOrSpaces(config.getModuleDepsFilename())) { parameters.add("-deps="+config.getModuleDepsFilename()); } if(config.isGenerateHeader()) { parameters.add("-H"); if( !StringUtil.isEmptyOrSpaces(config.getHeaderDir())) { parameters.add("-Hd"+config.getHeaderDir()); } if( !StringUtil.isEmptyOrSpaces(config.getHeaderFilename())) { parameters.add("-Hf"+config.getHeaderFilename()); } } if(config.isGenerateMap()) { parameters.add("-map"); } if(config.isNoObjectFiles()) { parameters.add("-o-"); } if(config.isNoStripPaths()) { parameters.add("-op"); } if(config.isGenerateJson()) { parameters.add("-X"); if( !StringUtil.isEmptyOrSpaces(config.getJsonFilename())) { parameters.add("-Xf"+config.getJsonFilename()); } } } private static void buildDebugParameters(DLangRunDmdConfiguration config, List<String> parameters) { if(config.isAddSymbolicDebugInfo()) { parameters.add("-g"); } if(config.isAddSymbolicDebugInfoC()) { parameters.add("-gc"); } if(config.isGenerateStandardStackFrame()) { parameters.add("-gs"); } if(config.isProfile()) { parameters.add("-profile"); } if( !StringUtil.isEmptyOrSpaces(config.getSymbolicLibrary()) ) { parameters.add("-debuglib="+config.getSymbolicLibrary()); } } @NotNull private static List<String> getAllDLangSources(final VirtualFile sourcesRoot, final VirtualFile[] excludedRoots) throws NoSourcesException, ExecutionException { DLangVirtualFileVisitor visitor = new DLangVirtualFileVisitor(sourcesRoot, excludedRoots); VfsUtilCore.visitChildrenRecursively(sourcesRoot, visitor); //Build list of *.D source files List<String> sources = visitor.getdLangSources(); if(sources.isEmpty()) { throw new NoSourcesException(sourcesRoot.getCanonicalPath()); } return sources; } }