basic rdmd support

This commit is contained in:
gazer 2016-01-28 03:24:10 +03:00
parent 13f2656550
commit e1d924dd7b
13 changed files with 171 additions and 51 deletions

View File

@ -16,14 +16,15 @@ alias BuildResultListener = void delegate(int);
class Builder : BackgroundOperationWatcher {
protected Project _project;
protected string _filename; // for rdmd
protected ExternalProcess _extprocess;
protected OutputPanel _log;
protected ProtectedTextStorage _box;
protected ProjectConfiguration _projectConfig;
protected BuildConfiguration _buildConfig;
protected BuildOperation _buildOp;
protected string _dubExecutable;
protected string _dubAdditionalParams;
protected string _executable;
protected string _additionalParams;
protected BuildResultListener _listener;
protected int _exitCode = int.min;
protected string _toolchain;
@ -44,8 +45,8 @@ class Builder : BackgroundOperationWatcher {
_projectConfig = projectConfig;
_buildConfig = buildConfig;
_buildOp = buildOp;
_dubExecutable = dubExecutable.empty ? "dub" : dubExecutable;
_dubAdditionalParams = dubAdditionalParams;
_executable = dubExecutable.empty ? "dub" : dubExecutable;
_additionalParams = dubAdditionalParams;
_project = project;
_log = log;
_toolchain = toolchain;
@ -54,6 +55,23 @@ class Builder : BackgroundOperationWatcher {
_box = new ProtectedTextStorage();
}
this(AppFrame frame, string filename, OutputPanel log, BuildConfiguration buildConfig,
BuildOperation buildOp,
string rdmdExecutable,
string rdmdAdditionalParams,
BuildResultListener listener = null) {
super(frame);
_listener = listener;
_buildOp = buildOp;
_filename = filename;
_buildConfig = buildConfig;
_executable = rdmdExecutable.empty ? "rdmd" : rdmdExecutable;
_additionalParams = rdmdAdditionalParams;
_log = log;
_extprocess = new ExternalProcess();
_box = new ProtectedTextStorage();
}
/// log lines
void pollText() {
dstring text = _box.readText();
@ -70,60 +88,84 @@ class Builder : BackgroundOperationWatcher {
ExternalProcessState state = _extprocess.state;
if (state == ExternalProcessState.None) {
_log.clear();
char[] program = _dubExecutable.dup;
char[] program = _executable.dup;
char[][] params;
char[] dir = _project.dir.dup;
char[] dir;
if (_buildOp == BuildOperation.Build || _buildOp == BuildOperation.Rebuild) {
params ~= "build".dup;
if (_buildOp == BuildOperation.Rebuild) {
params ~= "--force".dup;
}
if (!_arch.empty)
params ~= ("--arch=" ~ _arch).dup;
if (!_toolchain.empty)
params ~= ("--compiler=" ~ _toolchain).dup;
params ~= "--build-mode=allAtOnce".dup;
} else if (_buildOp == BuildOperation.Clean) {
params ~= "clean".dup;
} else if (_buildOp == BuildOperation.Run) {
if (_projectConfig.type == ProjectConfiguration.Type.Library) {
params ~= "test".dup;
} else {
params ~= "run".dup;
}
} else if (_buildOp == BuildOperation.Upgrade) {
params ~= "upgrade".dup;
params ~= "--force-remove".dup;
import std.path;
import std.file;
string projectFile = project.filename;
string selectionsFile = projectFile.stripExtension ~ ".selections.json";
if (selectionsFile.exists && selectionsFile.isFile) {
Log.i("Removing file ", selectionsFile);
remove(selectionsFile);
}
}
if(_buildOp == BuildOperation.RunWithRdmd) {
dir = std.path.dirName(_filename).dup;
if (!_additionalParams.empty)
params ~= _additionalParams.dup;
if (_buildOp != BuildOperation.Clean && _buildOp != BuildOperation.Upgrade) {
switch (_buildConfig) {
default:
case BuildConfiguration.Debug:
params ~= "--build=debug".dup;
params ~= "-debug".dup;
break;
case BuildConfiguration.Release:
params ~= "--build=release".dup;
params ~= "-release".dup;
break;
case BuildConfiguration.Unittest:
params ~= "--build=unittest".dup;
params ~= "-unittest".dup;
break;
}
if (!_dubAdditionalParams.empty)
params ~= _dubAdditionalParams.dup;
}
params ~= std.path.baseName(_filename).dup;
if(_projectConfig.name != ProjectConfiguration.DEFAULT_NAME) {
params ~= "--config=".dup ~ _projectConfig.name;
} else {
// dub
dir = _project.dir.dup;
if (_buildOp == BuildOperation.Build || _buildOp == BuildOperation.Rebuild) {
params ~= "build".dup;
if (_buildOp == BuildOperation.Rebuild) {
params ~= "--force".dup;
}
if (!_arch.empty)
params ~= ("--arch=" ~ _arch).dup;
if (!_toolchain.empty)
params ~= ("--compiler=" ~ _toolchain).dup;
params ~= "--build-mode=allAtOnce".dup;
} else if (_buildOp == BuildOperation.Clean) {
params ~= "clean".dup;
} else if (_buildOp == BuildOperation.Run) {
if (_projectConfig.type == ProjectConfiguration.Type.Library) {
params ~= "test".dup;
} else {
params ~= "run".dup;
}
} else if (_buildOp == BuildOperation.Upgrade) {
params ~= "upgrade".dup;
params ~= "--force-remove".dup;
import std.path;
import std.file;
string projectFile = project.filename;
string selectionsFile = projectFile.stripExtension ~ ".selections.json";
if (selectionsFile.exists && selectionsFile.isFile) {
Log.i("Removing file ", selectionsFile);
remove(selectionsFile);
}
}
if (_buildOp != BuildOperation.Clean && _buildOp != BuildOperation.Upgrade) {
switch (_buildConfig) {
default:
case BuildConfiguration.Debug:
params ~= "--build=debug".dup;
break;
case BuildConfiguration.Release:
params ~= "--build=release".dup;
break;
case BuildConfiguration.Unittest:
params ~= "--build=unittest".dup;
break;
}
if (!_additionalParams.empty)
params ~= _additionalParams.dup;
}
if(_projectConfig.name != ProjectConfiguration.DEFAULT_NAME) {
params ~= "--config=".dup ~ _projectConfig.name;
}
}
auto text = "Running (in " ~ dir ~ "): " ~ program ~ " " ~ params.join(' ') ~ "\n";

View File

@ -28,6 +28,7 @@ enum IDEActions : int {
UpdateProjectDependencies,
SetStartupProject,
ProjectSettings,
RunWithRdmd,
DebugStart,
DebugRestart,
@ -97,6 +98,7 @@ const Action ACTION_PROJECT_SET_STARTUP = new Action(IDEActions.SetStartupProjec
const Action ACTION_PROJECT_SETTINGS = (new Action(IDEActions.ProjectSettings, "MENU_PROJECT_SETTINGS"c, null)).disableByDefault();
const Action ACTION_PROJECT_REFRESH = new Action(IDEActions.RefreshProject, "MENU_PROJECT_REFRESH"c);
const Action ACTION_PROJECT_UPDATE_DEPENDENCIES = new Action(IDEActions.UpdateProjectDependencies, "MENU_PROJECT_UPDATE_DEPENDENCIES"c);
const Action ACTION_RUN_WITH_RDMD = new Action(IDEActions.RunWithRdmd, "MENU_BUILD_RUN_WITH_RDMD"c, "run-rdmd").disableByDefault();
const Action ACTION_DEBUG_START = new Action(IDEActions.DebugStart, "MENU_DEBUG_START_DEBUGGING"c, "debug-run"c, KeyCode.F5, KeyFlag.Control | KeyFlag.Shift);
const Action ACTION_DEBUG_START_NO_DEBUG = new Action(IDEActions.DebugStartNoDebug, "MENU_DEBUG_START_NO_DEBUGGING"c, null, KeyCode.F5, KeyFlag.Control);

View File

@ -405,6 +405,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
window.windowCaption(tab.text.value ~ " - "d ~ frameWindowCaptionSuffix);
}
requestActionsUpdate();
}
// returns DSourceEdit from currently active tab (if it's editor), null if current tab is not editor or no tabs open
@ -530,6 +531,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
closeTab(tabId);
}
}
requestActionsUpdate();
}
/// create app body widget
@ -560,10 +562,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
_logPanel.compilerLogIssueClickHandler = &onCompilerLogIssueClick;
_logPanel.appendText(null, "DlangIDE is started\nHINT: Try to open some DUB project\n"d);
string dubPath = findExecutablePath("dub");
string rdmdPath = findExecutablePath("rdmd");
string dmdPath = findExecutablePath("dmd");
string ldcPath = findExecutablePath("ldc2");
string gdcPath = findExecutablePath("gdc");
_logPanel.appendText(null, dubPath ? ("dub path: "d ~ toUTF32(dubPath) ~ "\n"d) : ("dub is not found! cannot build projects without DUB\n"d));
_logPanel.appendText(null, rdmdPath ? ("rdmd path: "d ~ toUTF32(rdmdPath) ~ "\n"d) : ("rdmd is not found!\n"d));
_logPanel.appendText(null, dmdPath ? ("dmd path: "d ~ toUTF32(dmdPath) ~ "\n"d) : ("dmd compiler is not found!\n"d));
_logPanel.appendText(null, ldcPath ? ("ldc path: "d ~ toUTF32(ldcPath) ~ "\n"d) : ("ldc compiler is not found!\n"d));
_logPanel.appendText(null, gdcPath ? ("gdc path: "d ~ toUTF32(gdcPath) ~ "\n"d) : ("gdc compiler is not found!\n"d));
@ -601,7 +605,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
MenuItem buildItem = new MenuItem(new Action(22, "MENU_BUILD"));
buildItem.add(ACTION_WORKSPACE_BUILD, ACTION_WORKSPACE_REBUILD, ACTION_WORKSPACE_CLEAN,
ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN);
ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN,
ACTION_RUN_WITH_RDMD);
MenuItem debugItem = new MenuItem(new Action(23, "MENU_DEBUG"));
debugItem.add(ACTION_DEBUG_START, ACTION_DEBUG_START_NO_DEBUG,
@ -652,8 +657,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
ACTION_FILE_SAVE, ACTION_FILE_SAVE_AS, ACTION_FILE_SAVE_ALL, ACTION_FILE_EXIT,
ACTION_PROJECT_SET_STARTUP, ACTION_PROJECT_REFRESH, ACTION_PROJECT_UPDATE_DEPENDENCIES,
ACTION_PROJECT_SETTINGS, ACTION_WORKSPACE_BUILD, ACTION_WORKSPACE_REBUILD, ACTION_WORKSPACE_CLEAN,
ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN, ACTION_DEBUG_START,
ACTION_DEBUG_START_NO_DEBUG, ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN, ACTION_RUN_WITH_RDMD,
ACTION_DEBUG_START, ACTION_DEBUG_START_NO_DEBUG, ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
ACTION_DEBUG_RESTART,
ACTION_DEBUG_STEP_INTO,
ACTION_DEBUG_STEP_OVER,
@ -692,7 +697,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
};
cbBuildConfiguration.action = ACTION_BUILD_CONFIGURATIONS;
tb.addControl(cbBuildConfiguration);
tb.addButtons(ACTION_PROJECT_BUILD);
tb.addButtons(ACTION_PROJECT_BUILD, ACTION_SEPARATOR, ACTION_RUN_WITH_RDMD);
tb = res.getOrAddToolbar("Edit");
tb.addButtons(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_SEPARATOR,
@ -744,6 +749,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
else
a.state = ACTION_STATE_DISABLE;
return true;
case IDEActions.RunWithRdmd:
// enable when D source file is in current tab
if (currentEditor && !_currentBackgroundOperation && currentEditor.id.endsWith(".d"))
a.state = ACTION_STATE_ENABLED;
else
a.state = ACTION_STATE_DISABLE;
return true;
case IDEActions.DebugStop:
a.state = isExecutionActive ? ACTION_STATE_ENABLED : ACTION_STATE_DISABLE;
return true;
@ -820,6 +832,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
case IDEActions.CleanWorkspace:
buildProject(BuildOperation.Clean, cast(Project)a.objectParam);
return true;
case IDEActions.RunWithRdmd:
runWithRdmd(currentEditor.id);
return true;
case IDEActions.DebugStartNoDebug:
buildAndRunProject(cast(Project)a.objectParam);
return true;
@ -1320,6 +1335,16 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
setBackgroundOperation(op);
}
void runWithRdmd(string filename, BuildResultListener listener = null) {
string rdmdExecutable = _settings.rdmdExecutable;
string rdmdAdditionalParams = _settings.rdmdAdditionalParams;
Builder op = new Builder(this, filename, _logPanel, currentWorkspace ? currentWorkspace.buildConfiguration : BuildConfiguration.Debug,
BuildOperation.RunWithRdmd,
rdmdExecutable, rdmdAdditionalParams,
listener);
setBackgroundOperation(op);
}
/// updates list of available configurations
void setProjectConfigurations(dstring[] items) {
projectConfigurationCombo.items = items;

View File

@ -26,6 +26,9 @@ SettingsPage createSettingsPages() {
SettingsPage dub = dlang.addChild("dlang/dub", UIString("DUB"d));
dub.addExecutableFileNameEdit("dlang/dub/executable", UIString("DUB executable"d), "dub");
dub.addStringEdit("dlang/dub/additional_params", UIString("DUB additional params"d), "");
SettingsPage rdmd = dlang.addChild("dlang/rdmd", UIString("rdmd"d));
rdmd.addExecutableFileNameEdit("dlang/rdmd/executable", UIString("rdmd executable"d), "rdmd");
rdmd.addStringEdit("dlang/rdmd/additional_params", UIString("rdmd additional params"d), "");
SettingsPage ddebug = dlang.addChild("dlang/debugger", UIString("Debugger"d));
ddebug.addExecutableFileNameEdit("dlang/debugger/executable", UIString("Debugger executable"d), "gdb");
SettingsPage terminal = dlang.addChild("dlang/terminal", UIString("Terminal"d));

View File

@ -30,6 +30,8 @@ class IDESettings : SettingsFile {
terminalSettings.setStringDef("executable", "xterm");
dubSettings.setStringDef("executable", "dub");
dubSettings.setStringDef("additional_params", "");
rdmdSettings.setStringDef("executable", "rdmd");
rdmdSettings.setStringDef("additional_params", "");
dmdToolchainSettings.setStringDef("executable", "dmd");
dmdToolchainSettings.setStringDef("dub_additional_params", "");
ldcToolchainSettings.setStringDef("executable", "ldc2");
@ -69,6 +71,11 @@ class IDESettings : SettingsFile {
return res;
}
@property Setting rdmdSettings() {
Setting res = _setting.objectByPath("dlang/rdmd", true);
return res;
}
@property Setting dmdToolchainSettings() {
Setting res = _setting.objectByPath("dlang/toolchains/dmd", true);
return res;
@ -181,6 +188,14 @@ class IDESettings : SettingsFile {
return dubSettings.getString("additional_params", "");
}
@property string rdmdExecutable() {
return rdmdSettings.getString("executable", "rdmd");
}
@property string rdmdAdditionalParams() {
return rdmdSettings.getString("additional_params", "");
}
string getToolchainCompilerExecutable(string toolchainName) {
if (toolchainName.equal("dmd"))
return dmdToolchainSettings.getString("executable", "dmd");

View File

@ -69,7 +69,7 @@ class ProjectSettings : SettingsFile {
}
/// join parameter lists separating with space
string joinParams(string[] params...) {
string joinParams(string[] params...) pure {
char[] res;
foreach(param; params) {
string s = param.strip;

View File

@ -19,7 +19,8 @@ enum BuildOperation {
Clean,
Rebuild,
Run,
Upgrade
Upgrade,
RunWithRdmd
}
enum BuildConfiguration {

View File

@ -49,6 +49,7 @@ MENU_BUILD_WORKSPACE_CLEAN=Clean workspace
MENU_BUILD_PROJECT_BUILD=Build project
MENU_BUILD_PROJECT_REBUILD=Rebuild project
MENU_BUILD_PROJECT_CLEAN=Clean project
MENU_BUILD_RUN_WITH_RDMD=Run with rdmd
MENU_DEBUG=&Debug
MENU_DEBUG_START_DEBUGGING=Start debugging

View File

@ -45,6 +45,7 @@ MENU_BUILD_WORKSPACE_CLEAN=Очистить workspace
MENU_BUILD_PROJECT_BUILD=Собрать проект
MENU_BUILD_PROJECT_REBUILD=Пересобрать проект
MENU_BUILD_PROJECT_CLEAN=Очистить проект
MENU_BUILD_RUN_WITH_RDMD=Запустить с rdmd
MENU_DEBUG=&Отладка

BIN
views/res/mdpi/run-rdmd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

View File

@ -62,6 +62,7 @@ res/mdpi/project-open.png
res/mdpi/run-build.png
res/mdpi/run-build-clean.png
res/mdpi/run-build-configure.png
res/mdpi/run-rdmd.png
res/mdpi/text-d.png
res/mdpi/text-dml.png
res/mdpi/text-json.png

View File

@ -0,0 +1,7 @@
module for_rdmd_test;
int inc(int x)
{
return x + 1;
}

22
workspaces/rdmd_test.d Normal file
View File

@ -0,0 +1,22 @@
import std.stdio;
import for_rdmd_test;
void main()
{
writeln("test!");
debug writeln("I am in debug mode");
writeln(inc(10));
}
int f(int x)
{
return x*x;
}
unittest {
writeln("unittest!");
assert(f(0) == 0);
assert(f(5) == 25);
assert(f(-5) == 25);
}