Convert runtime environment to kotlin

This commit is contained in:
Mike Cifelli 2018-03-25 11:01:24 -04:00
parent b2989809eb
commit 26709a7f9e
22 changed files with 239 additions and 377 deletions

View File

@ -1,154 +0,0 @@
package environment;
import error.ErrorManager;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.function.Function;
public class RuntimeEnvironment {
private static RuntimeEnvironment uniqueInstance = new RuntimeEnvironment();
public static RuntimeEnvironment getInstance() {
return uniqueInstance;
}
private String inputName;
private InputStream input;
private PrintStream output;
private PrintStream errorOutput;
private ErrorManager errorManager;
private String path;
private Runnable terminationFunction;
private Runnable errorTerminationFunction;
private Function<String, String> promptDecorator;
private Function<String, String> valueOutputDecorator;
private Function<String, String> warningOutputDecorator;
private Function<String, String> errorOutputDecorator;
private Function<String, String> criticalOutputDecorator;
private RuntimeEnvironment() {
reset();
}
public void reset() {
inputName = null;
input = null;
output = null;
errorOutput = null;
errorManager = null;
path = null;
terminationFunction = null;
errorTerminationFunction = null;
promptDecorator = null;
valueOutputDecorator = null;
warningOutputDecorator = null;
errorOutputDecorator = null;
criticalOutputDecorator = null;
}
public void setInputName(String inputName) {
this.inputName = inputName;
}
public void setInput(InputStream input) {
this.input = input;
}
public void setOutput(PrintStream output) {
this.output = output;
}
public void setErrorOutput(PrintStream errorOutput) {
this.errorOutput = errorOutput;
}
public void setErrorManager(ErrorManager errorManager) {
this.errorManager = errorManager;
}
public void setPath(String path) {
this.path = path;
}
public void setTerminationFunction(Runnable terminationFunction) {
this.terminationFunction = terminationFunction;
}
public void setErrorTerminationFunction(Runnable errorTerminationFunction) {
this.errorTerminationFunction = errorTerminationFunction;
}
public void setPromptDecorator(Function<String, String> promptDecorator) {
this.promptDecorator = promptDecorator;
}
public void setValueOutputDecorator(Function<String, String> valueOutputDecorator) {
this.valueOutputDecorator = valueOutputDecorator;
}
public void setWarningOutputDecorator(Function<String, String> warningOutputDecorator) {
this.warningOutputDecorator = warningOutputDecorator;
}
public void setErrorOutputDecorator(Function<String, String> errorOutputDecorator) {
this.errorOutputDecorator = errorOutputDecorator;
}
public void setCriticalOutputDecorator(Function<String, String> criticalOutputDecorator) {
this.criticalOutputDecorator = criticalOutputDecorator;
}
public String getInputName() {
return inputName;
}
public InputStream getInput() {
return input;
}
public PrintStream getOutput() {
return output;
}
public PrintStream getErrorOutput() {
return errorOutput;
}
public ErrorManager getErrorManager() {
return errorManager;
}
public String getPath() {
return path;
}
public void terminateSuccessfully() {
terminationFunction.run();
}
public void terminateExceptionally() {
errorTerminationFunction.run();
}
public String decoratePrompt(String prompt) {
return promptDecorator.apply(prompt);
}
public String decorateValueOutput(String valueOutput) {
return valueOutputDecorator.apply(valueOutput);
}
public String decorateWarningOutput(String warningOutput) {
return warningOutputDecorator.apply(warningOutput);
}
public String decorateErrorOutput(String errorOutput) {
return errorOutputDecorator.apply(errorOutput);
}
public String decorateCriticalOutput(String criticalOutput) {
return criticalOutputDecorator.apply(criticalOutput);
}
}

View File

@ -0,0 +1,56 @@
package environment
import error.ErrorManager
import java.io.InputStream
import java.io.PrintStream
import java.util.function.Function
object RuntimeEnvironment {
var inputName: String? = null
var input: InputStream? = null
var output: PrintStream? = null
var errorOutput: PrintStream? = null
var errorManager: ErrorManager? = null
var path: String? = null
// TODO - convert to function types ()-> Unit etc... once calling code is kotlin
var terminationFunction: Runnable? = null
var errorTerminationFunction: Runnable? = null
var promptDecorator: Function<String, String>? = null
var valueOutputDecorator: Function<String, String>? = null
var warningOutputDecorator: Function<String, String>? = null
var errorOutputDecorator: Function<String, String>? = null
var criticalOutputDecorator: Function<String, String>? = null
fun reset() {
inputName = null
input = null
output = null
errorOutput = null
errorManager = null
path = null
terminationFunction = null
errorTerminationFunction = null
promptDecorator = null
valueOutputDecorator = null
warningOutputDecorator = null
errorOutputDecorator = null
criticalOutputDecorator = null
}
fun terminateSuccessfully() {
terminationFunction!!.run()
}
fun terminateExceptionally() {
errorTerminationFunction!!.run()
}
fun decoratePrompt(prompt: String) = promptDecorator!!.apply(prompt)
fun decorateValueOutput(valueOutput: String) = valueOutputDecorator!!.apply(valueOutput)
fun decorateWarningOutput(warningOutput: String) = warningOutputDecorator!!.apply(warningOutput)
fun decorateErrorOutput(errorOutput: String) = errorOutputDecorator!!.apply(errorOutput)
fun decorateCriticalOutput(criticalOutput: String) = criticalOutputDecorator!!.apply(criticalOutput)
}

View File

@ -11,13 +11,11 @@ import java.text.MessageFormat.format
*/
class ErrorManager {
private val environment: RuntimeEnvironment = RuntimeEnvironment.getInstance()
fun handle(lispException: LispException) {
printMessage(lispException)
if (isCritical(lispException))
environment.terminateExceptionally()
RuntimeEnvironment.terminateExceptionally()
}
private fun printMessage(lispException: LispException) {
@ -26,7 +24,7 @@ class ErrorManager {
}
private fun selectOutputStream(severity: Severity): PrintStream {
return if (severity === WARNING) environment.output else environment.errorOutput
return if (severity === WARNING) RuntimeEnvironment.output!! else RuntimeEnvironment.errorOutput!!
}
private fun formatMessage(lispException: LispException): String {
@ -34,7 +32,7 @@ class ErrorManager {
val prefix = severity.toDisplayString()
val message = format("[{0}] {1}", prefix, lispException.message)
return severity.decorate(message, environment)
return severity.decorate(message, RuntimeEnvironment)
}
private fun isCritical(lispException: LispException) = lispException.severity == CRITICAL

View File

@ -6,21 +6,21 @@ enum class Severity {
WARNING {
override fun decorate(output: String, environment: RuntimeEnvironment): String =
environment.decorateWarningOutput(output)
RuntimeEnvironment.decorateWarningOutput(output)!!
override fun toDisplayString() = "warning"
},
ERROR {
override fun decorate(output: String, environment: RuntimeEnvironment): String =
environment.decorateErrorOutput(output)
RuntimeEnvironment.decorateErrorOutput(output)!!
override fun toDisplayString() = "error"
},
CRITICAL {
override fun decorate(output: String, environment: RuntimeEnvironment): String =
environment.decorateCriticalOutput(output)
RuntimeEnvironment.decorateCriticalOutput(output)!!
override fun toDisplayString() = "critical"
};

View File

@ -18,7 +18,7 @@ public class EXIT extends LispFunction {
public EXIT(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setMaximumNumberOfArguments(0);
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
@Override

View File

@ -32,7 +32,7 @@ public class LOAD extends LispFunction {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setExactNumberOfArguments(1);
this.argumentValidator.setEveryArgumentExpectedType(LispString.class);
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
@Override

View File

@ -16,7 +16,7 @@ public class PRINT extends LispFunction {
public PRINT(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setExactNumberOfArguments(1);
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
@Override

View File

@ -31,7 +31,7 @@ public abstract class Define extends LispSpecialFunction {
this.lambdaListValidator = new ArgumentValidator(functionName + "|parameter|");
this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class);
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
@Override

View File

@ -16,7 +16,7 @@ public class LispInterpreter {
private LispParser parser;
public LispInterpreter() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
public void interpretLanguageFiles(List<LanguageFile> languageFiles) {

View File

@ -40,7 +40,7 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
protected boolean isBuilt;
protected LispInterpreterBuilderImpl() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
this.inputName = "";
this.isInteractive = true;
this.isFileBased = false;

View File

@ -20,7 +20,7 @@ public class LispInterpreterFixture {
private static ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
private static ExecutionContext executionContext = ExecutionContext.INSTANCE;
private static RuntimeEnvironment environment = RuntimeEnvironment.getInstance();
private static RuntimeEnvironment environment = RuntimeEnvironment.INSTANCE;
private static LispInterpreter interpreter = null;
public static void resetInterpreter() {

View File

@ -32,7 +32,7 @@ public class MainTest extends SymbolAndFunctionCleaner {
private CountDownLatch latch;
public MainTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private void runInterpreterWithFile(String fileName) {

View File

@ -1,199 +0,0 @@
package environment;
import error.ErrorManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class RuntimeEnvironmentTest {
private static final String TERMINATED_SUCCESSFULLY = "TERMINATED_SUCCESSFULLY";
private static final String TERMINATED_EXCEPTIONALLY = "TERMINATED_EXCEPTIONALLY";
private RuntimeEnvironment environment;
private Set<String> indicatorSet;
public RuntimeEnvironmentTest() {
this.environment = RuntimeEnvironment.getInstance();
}
@Before
public void setUp() {
indicatorSet = new HashSet<>();
environment.reset();
}
@After
public void tearDown() {
environment.reset();
}
@Test
public void assignInputName() {
environment.setInputName("test");
assertEquals("test", environment.getInputName());
}
@Test
public void assignInput() {
environment.setInput(System.in);
assertEquals(System.in, environment.getInput());
}
@Test
public void assignOutput() {
environment.setOutput(System.out);
assertEquals(System.out, environment.getOutput());
}
@Test
public void assignErrorOutput() {
environment.setErrorOutput(System.err);
assertEquals(System.err, environment.getErrorOutput());
}
@Test
public void assignErrorManager() {
ErrorManager errorManager = new ErrorManager();
environment.setErrorManager(errorManager);
assertEquals(errorManager, environment.getErrorManager());
}
@Test
public void assignPath() {
environment.setPath("testpath/");
assertEquals("testpath/", environment.getPath());
}
@Test
public void assignTerminationFunction() {
environment.setTerminationFunction(() -> indicatorSet.add(TERMINATED_SUCCESSFULLY));
environment.terminateSuccessfully();
assertTrue(indicatorSet.contains(TERMINATED_SUCCESSFULLY));
}
@Test
public void assignErrorTerminationFunction() {
environment.setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED_EXCEPTIONALLY));
environment.terminateExceptionally();
assertTrue(indicatorSet.contains(TERMINATED_EXCEPTIONALLY));
}
@Test
public void assignPromptDecorator() {
environment.setPromptDecorator(s -> "[" + s + "]");
assertEquals("[test]", environment.decoratePrompt("test"));
}
@Test
public void assignValueOutputDecorator() {
environment.setValueOutputDecorator(s -> "(" + s + ")");
assertEquals("(test)", environment.decorateValueOutput("test"));
}
@Test
public void assignWarningOutputDecorator() {
environment.setWarningOutputDecorator(s -> "|" + s + "|");
assertEquals("|test|", environment.decorateWarningOutput("test"));
}
@Test
public void assignErrorOutputDecorator() {
environment.setErrorOutputDecorator(s -> "{" + s + "}");
assertEquals("{test}", environment.decorateErrorOutput("test"));
}
@Test
public void assignCriticalOutputDecorator() {
environment.setCriticalOutputDecorator(s -> "/" + s + "/");
assertEquals("/test/", environment.decorateCriticalOutput("test"));
}
@Test
public void resetWorks() {
environment.setInputName("test");
environment.setInput(System.in);
environment.setOutput(System.out);
environment.setErrorOutput(System.err);
environment.setErrorManager(new ErrorManager());
environment.setPath("testpath/");
environment.setTerminationFunction(() -> indicatorSet.add(TERMINATED_SUCCESSFULLY));
environment.setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED_EXCEPTIONALLY));
environment.setPromptDecorator(s -> "[" + s + "]");
environment.setValueOutputDecorator(s -> "(" + s + ")");
environment.setWarningOutputDecorator(s -> "|" + s + "|");
environment.setErrorOutputDecorator(s -> "{" + s + "}");
environment.setCriticalOutputDecorator(s -> "/" + s + "/");
environment.reset();
assertNull(environment.getInputName());
assertNull(environment.getInput());
assertNull(environment.getOutput());
assertNull(environment.getErrorOutput());
assertNull(environment.getErrorManager());
assertNull(environment.getPath());
try {
environment.terminateSuccessfully();
fail("terminateSuccessfully");
} catch (NullPointerException e) {
}
try {
environment.terminateExceptionally();
fail("terminateExceptionally");
} catch (NullPointerException e) {
}
try {
environment.decoratePrompt("");
fail("decoratePrompt");
} catch (NullPointerException e) {
}
try {
environment.decorateValueOutput("");
fail("decorateValueOutput");
} catch (NullPointerException e) {
}
try {
environment.decorateWarningOutput("");
fail("decorateWarningOutput");
} catch (NullPointerException e) {
}
try {
environment.decorateErrorOutput("");
fail("decorateErrorOutput");
} catch (NullPointerException e) {
}
try {
environment.decorateCriticalOutput("");
fail("decorateCriticalOutput");
} catch (NullPointerException e) {
}
}
}

View File

@ -0,0 +1,161 @@
package environment
import error.ErrorManager
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
import org.junit.jupiter.api.Assertions.assertThrows
import java.util.HashSet
import java.util.function.Function
@TestInstance(PER_CLASS)
class RuntimeEnvironmentTest {
companion object {
private const val TERMINATED_SUCCESSFULLY = "TERMINATED_SUCCESSFULLY"
private const val TERMINATED_EXCEPTIONALLY = "TERMINATED_EXCEPTIONALLY"
}
private var indicatorSet: MutableSet<String>? = null
@BeforeEach
fun setUp() {
indicatorSet = HashSet()
RuntimeEnvironment.reset()
}
@AfterEach
fun tearDown() {
RuntimeEnvironment.reset()
}
@Test
fun assignInputName() {
RuntimeEnvironment.inputName = "test"
assertThat(RuntimeEnvironment.inputName).isEqualTo("test")
}
@Test
fun assignInput() {
RuntimeEnvironment.input = System.`in`
assertThat(RuntimeEnvironment.input).isEqualTo(System.`in`)
}
@Test
fun assignOutput() {
RuntimeEnvironment.output = System.out
assertThat(RuntimeEnvironment.output).isEqualTo(System.out)
}
@Test
fun assignErrorOutput() {
RuntimeEnvironment.errorOutput = System.err
assertThat(RuntimeEnvironment.errorOutput).isEqualTo(System.err)
}
@Test
fun assignErrorManager() {
val errorManager = ErrorManager()
RuntimeEnvironment.errorManager = errorManager
assertThat(RuntimeEnvironment.errorManager).isEqualTo(errorManager)
}
@Test
fun assignPath() {
RuntimeEnvironment.path = "testpath/"
assertThat(RuntimeEnvironment.path).isEqualTo("testpath/")
}
@Test
fun assignTerminationFunction() {
RuntimeEnvironment.terminationFunction = Runnable { indicatorSet!!.add(TERMINATED_SUCCESSFULLY) }
RuntimeEnvironment.terminateSuccessfully()
assertThat(indicatorSet!!.contains(TERMINATED_SUCCESSFULLY)).isTrue()
}
@Test
fun assignErrorTerminationFunction() {
RuntimeEnvironment.errorTerminationFunction = Runnable { indicatorSet!!.add(TERMINATED_EXCEPTIONALLY) }
RuntimeEnvironment.terminateExceptionally()
assertThat(indicatorSet!!.contains(TERMINATED_EXCEPTIONALLY)).isTrue()
}
@Test
fun assignPromptDecorator() {
RuntimeEnvironment.promptDecorator = Function { s -> "[$s]" }
assertThat(RuntimeEnvironment.decoratePrompt("test")).isEqualTo("[test]")
}
@Test
fun assignValueOutputDecorator() {
RuntimeEnvironment.valueOutputDecorator = Function { s -> "($s)" }
assertThat(RuntimeEnvironment.decorateValueOutput("test")).isEqualTo("(test)")
}
@Test
fun assignWarningOutputDecorator() {
RuntimeEnvironment.warningOutputDecorator = Function { s -> "|$s|" }
assertThat(RuntimeEnvironment.decorateWarningOutput("test")).isEqualTo("|test|")
}
@Test
fun assignErrorOutputDecorator() {
RuntimeEnvironment.errorOutputDecorator = Function { s -> "{$s}" }
assertThat(RuntimeEnvironment.decorateErrorOutput("test")).isEqualTo("{test}")
}
@Test
fun assignCriticalOutputDecorator() {
RuntimeEnvironment.criticalOutputDecorator = Function { s -> "/$s/" }
assertThat(RuntimeEnvironment.decorateCriticalOutput("test")).isEqualTo("/test/")
}
@Test
fun resetWorks() {
RuntimeEnvironment.inputName = "test"
RuntimeEnvironment.input = System.`in`
RuntimeEnvironment.output = System.out
RuntimeEnvironment.errorOutput = System.err
RuntimeEnvironment.errorManager = ErrorManager()
RuntimeEnvironment.path = "testpath/"
RuntimeEnvironment.terminationFunction = Runnable { indicatorSet!!.add(TERMINATED_SUCCESSFULLY) }
RuntimeEnvironment.errorTerminationFunction = Runnable { indicatorSet!!.add(TERMINATED_EXCEPTIONALLY) }
RuntimeEnvironment.promptDecorator = Function { s -> "[$s]" }
RuntimeEnvironment.valueOutputDecorator = Function { s -> "($s)" }
RuntimeEnvironment.warningOutputDecorator = Function { s -> "|$s|" }
RuntimeEnvironment.errorOutputDecorator = Function { s -> "{$s}" }
RuntimeEnvironment.criticalOutputDecorator = Function { s -> "/$s/" }
RuntimeEnvironment.reset()
assertThat(RuntimeEnvironment.inputName).isNull()
assertThat(RuntimeEnvironment.input).isNull()
assertThat(RuntimeEnvironment.output).isNull()
assertThat(RuntimeEnvironment.errorOutput).isNull()
assertThat(RuntimeEnvironment.errorManager).isNull()
assertThat(RuntimeEnvironment.path).isNull()
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.terminateSuccessfully() }
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.terminateExceptionally() }
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decoratePrompt("") }
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateValueOutput("") }
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateWarningOutput("") }
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateErrorOutput("") }
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateCriticalOutput("") }
}
}

View File

@ -27,7 +27,7 @@ public class ErrorManagerTest {
private RuntimeEnvironment environment;
public ErrorManagerTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private ErrorManager createErrorManagerWithIndicators() {

View File

@ -19,7 +19,7 @@ public class EXITTest extends SymbolAndFunctionCleaner {
private Set<String> indicatorSet;
public EXITTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private void assertTerminated() {

View File

@ -23,7 +23,7 @@ public class LOADTest extends SymbolAndFunctionCleaner {
private RuntimeEnvironment environment;
public LOADTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private void assertWarningMessagePrinted() {

View File

@ -19,7 +19,7 @@ public class PRINTTest extends SymbolAndFunctionCleaner {
private ByteArrayOutputStream outputStream;
public PRINTTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private void assertPrinted(String expected) {

View File

@ -24,7 +24,7 @@ public class DEFINE_SPECIALTest extends SymbolAndFunctionCleaner {
private RuntimeEnvironment environment;
public DEFINE_SPECIALTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private void assertSomethingPrinted() {

View File

@ -24,7 +24,7 @@ public class DEFMACROTest extends SymbolAndFunctionCleaner {
private RuntimeEnvironment environment;
public DEFMACROTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private void assertSomethingPrinted() {

View File

@ -24,7 +24,7 @@ public class DEFUNTest extends SymbolAndFunctionCleaner {
private RuntimeEnvironment environment;
public DEFUNTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
}
private void assertSomethingPrinted() {

View File

@ -32,7 +32,7 @@ public class LispInterpreterTest {
private LispInterpreterBuilder builder;
public LispInterpreterTest() {
this.environment = RuntimeEnvironment.getInstance();
this.environment = RuntimeEnvironment.INSTANCE;
this.builder = new LispInterpreterBuilderImpl() {