/
InterpreterLaunchConfigurationDelegate.scala
139 lines (118 loc) · 4.54 KB
/
InterpreterLaunchConfigurationDelegate.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* Copyright 2005-2010 LAMP/EPFL
*/
// $Id$
package scala.tools.eclipse.interpreter
import java.io.File
import org.eclipse.core.runtime.IProgressMonitor
import org.eclipse.core.runtime.NullProgressMonitor
import org.eclipse.debug.core.ILaunch
import org.eclipse.debug.core.ILaunchConfiguration
import org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate
import org.eclipse.jdt.launching.ExecutionArguments
import org.eclipse.jdt.launching.VMRunnerConfiguration
import scala.tools.eclipse.ScalaPlugin
/**
* This launch delegate extends the normal JavaLaunchDelegate with functionality to work for the interpreter.
*/
class InterpreterLaunchConfigurationDelegate extends AbstractJavaLaunchConfigurationDelegate {
override def launch(configuration : ILaunchConfiguration, mode : String, launch : ILaunch, monitor : IProgressMonitor) {
val mon : IProgressMonitor = if(monitor == null) new NullProgressMonitor() else monitor
//Helper method to actually perform the launch inside a try-catch block.
def doTheLaunch() {
val mainClass = "scala.tools.nsc.MainGenericRunner"
mon.beginTask(configuration.getName(), 3); //$NON-NLS-1$
//We need lots of early outs if possible...
if(mon.isCanceled) {
return;
}
val vmRunner = getVMRunner(configuration, mode)
//TODO - Check for null/existence of working directory... (should this always be defined?)
val workingDir = {
val dir = getWorkingDirectory(configuration)
if(dir != null) {
dir.getAbsolutePath
} else {
null
}
}
val envp = getEnvironment(configuration)
val vmAttrs = getVMSpecificAttributesMap(configuration)
val execArgs = new ExecutionArguments(getVMArguments(configuration), getProgramArguments(configuration))
val vmArgs = execArgs.getVMArgumentsArray()
val classpath = (toolClassPath ++ getClasspath(configuration)).mkString(File.pathSeparator)
val programArgs = Array("-Xnojline", "-classpath", classpath) ++ execArgs.getProgramArgumentsArray()
val runConfig = new VMRunnerConfiguration(mainClass, toolClassPath.toArray);
runConfig.setWorkingDirectory(workingDir);
runConfig.setEnvironment(envp);
runConfig.setVMArguments(vmArgs);
runConfig.setVMSpecificAttributesMap(vmAttrs);
runConfig.setProgramArguments(programArgs);
// Bootpath - TODO - Add scala library/compiler here
runConfig.setBootClassPath(getBootpath(configuration));
// check for cancellation (again)
if (mon.isCanceled()) {
return;
}
// done the verification phase
mon.worked(1);
// set the default source locator if required
setDefaultSourceLocator(launch, configuration);
mon.worked(1);
// Launch the configuration
vmRunner.run(runConfig, launch, monitor);
//send extra commands to the configuration
if(mon.isCanceled) {
return;
}
runSeedscripts()
// check for cancellation
if (mon.isCanceled()) {
return;
}
}
/** Helper class to deal with launch configuration */
implicit class RichConfiguration(configuration : ILaunchConfiguration) {
def getAttributeOption(name : String) : Option[String] = {
configuration.getAttribute(name, "") match {
case null | "" => None
case x => Some(x)
}
}
}
/** Seeds the interpreter with imports */
def runSeedscripts() {
import InterpreterLaunchConstants._
def seedInterpreter(namespace : Option[String], asNamespace : Boolean) {
for {pkg <- namespace
process <- launch.getProcesses
streamProxy = process.getStreamsProxy
if streamProxy != null
} {
//TODO - Don't just write, flush!
if(asNamespace) {
streamProxy.write("import " + pkg + "._")
} else {
streamProxy.write(pkg)
}
//TODO - Is this needed?
streamProxy.write("\r\n")
}
}
seedInterpreter(configuration.getAttributeOption(SEED_SCRIPT), false)
seedInterpreter(configuration.getAttributeOption(PACKAGE_IMPORT), true)
seedInterpreter(configuration.getAttributeOption(OBJECT_IMPORT), true)
}
try {
doTheLaunch()
} finally {
mon.done();
}
}
/** Retreives the extra classpath needed for the interpreter*/
def toolClassPath = {
val plugin = ScalaPlugin.plugin
import plugin._
(libClasses :: swingClasses :: compilerClasses :: reflectClasses :: Nil).flatMap(_.toList).map(_.toOSString)
}
}