Convert token factory to kotlin

This commit is contained in:
Mike Cifelli 2018-05-19 11:13:28 -04:00
parent 053ca4852c
commit ac290d4997
7 changed files with 189 additions and 225 deletions

View File

@ -1,44 +0,0 @@
package token;
import error.CriticalLineColumnException;
import error.LineColumnException;
import file.FilePosition;
import static java.text.MessageFormat.format;
public interface TokenFactory {
Token createToken(String text, FilePosition position);
Token createEofToken(FilePosition position);
public static class EmptyTokenTextException extends CriticalLineColumnException {
private static final long serialVersionUID = 1L;
public EmptyTokenTextException(FilePosition position) {
super(position);
}
@Override
public String getMessagePrefix() {
return "empty token";
}
}
public static class BadCharacterException extends LineColumnException {
private static final long serialVersionUID = 1L;
private String text;
public BadCharacterException(String text, FilePosition position) {
super(position);
this.text = text;
}
@Override
public String getMessagePrefix() {
return format("illegal character >>{0}<<", text);
}
}
}

View File

@ -0,0 +1,21 @@
package token
import error.CriticalLineColumnException
import error.LineColumnException
import file.FilePosition
interface TokenFactory {
fun createToken(text: String, position: FilePosition): Token
fun createEofToken(position: FilePosition): Token
class EmptyTokenTextException(position: FilePosition) : CriticalLineColumnException(position) {
override val messagePrefix: String
get() = "empty token"
}
class BadCharacterException(private val text: String, position: FilePosition) : LineColumnException(position) {
override val messagePrefix: String
get() = "illegal character >>$text<<"
}
}

View File

@ -1,58 +0,0 @@
package token;
import file.FilePosition;
import util.Characters;
import static java.lang.Character.isDigit;
public class TokenFactoryImpl implements TokenFactory {
@Override
public Token createToken(String text, FilePosition position) {
if (text.length() == 0)
throw new EmptyTokenTextException(position);
char firstCharacter = text.charAt(0);
switch (firstCharacter) {
case Characters.LEFT_PARENTHESIS:
return new LeftParenthesis(text, position);
case Characters.RIGHT_PARENTHESIS:
return new RightParenthesis(text, position);
case Characters.SINGLE_QUOTE:
return new QuoteMark(text, position);
case Characters.DOUBLE_QUOTE:
return new QuotedString(text, position);
case Characters.BACKQUOTE:
return new Backquote(text, position);
case Characters.AT_SIGN:
return new AtSign(text, position);
case Characters.COMMA:
return new Comma(text, position);
default:
if (isNumeric(firstCharacter, text))
return new Number(text, position);
else if (Characters.INSTANCE.isLegalIdentifierCharacter(firstCharacter))
return new Identifier(text, position);
}
throw new BadCharacterException(text, position);
}
private boolean isNumeric(char firstCharacter, String text) {
return isDigit(firstCharacter) || isPrefixedNumeric(firstCharacter, text);
}
private boolean isPrefixedNumeric(char firstCharacter, String text) {
return Characters.INSTANCE.isNumberPrefix(firstCharacter) && isNextCharacterDigit(text);
}
private boolean isNextCharacterDigit(String text) {
return (text.length() > 1) && isDigit(text.charAt(1));
}
@Override
public Token createEofToken(FilePosition position) {
return new Eof("EOF", position);
}
}

View File

@ -0,0 +1,56 @@
package token
import file.FilePosition
import token.TokenFactory.BadCharacterException
import token.TokenFactory.EmptyTokenTextException
import util.Characters.AT_SIGN
import util.Characters.BACKQUOTE
import util.Characters.COMMA
import util.Characters.DOUBLE_QUOTE
import util.Characters.LEFT_PARENTHESIS
import util.Characters.RIGHT_PARENTHESIS
import util.Characters.SINGLE_QUOTE
import util.Characters.isLegalIdentifierCharacter
import util.Characters.isNumberPrefix
import java.lang.Character.isDigit
class TokenFactoryImpl : TokenFactory {
override fun createToken(text: String, position: FilePosition): Token {
if (text.isEmpty())
throw EmptyTokenTextException(position)
val firstCharacter = text[0]
return when (firstCharacter) {
LEFT_PARENTHESIS -> LeftParenthesis(text, position)
RIGHT_PARENTHESIS -> RightParenthesis(text, position)
SINGLE_QUOTE -> QuoteMark(text, position)
DOUBLE_QUOTE -> QuotedString(text, position)
BACKQUOTE -> Backquote(text, position)
AT_SIGN -> AtSign(text, position)
COMMA -> Comma(text, position)
else -> when {
isNumeric(firstCharacter, text) -> Number(text, position)
isLegalIdentifierCharacter(firstCharacter) -> Identifier(text, position)
else -> throw BadCharacterException(text, position)
}
}
}
override fun createEofToken(position: FilePosition): Token {
return Eof("EOF", position)
}
private fun isNumeric(firstCharacter: Char, text: String): Boolean {
return isDigit(firstCharacter) || isPrefixedNumeric(firstCharacter, text)
}
private fun isPrefixedNumeric(firstCharacter: Char, text: String): Boolean {
return isNumberPrefix(firstCharacter) && isNextCharacterDigit(text)
}
private fun isNextCharacterDigit(text: String): Boolean {
return text.length > 1 && isDigit(text[1])
}
}

View File

@ -5,10 +5,13 @@ import function.ArgumentValidator.TooManyArgumentsException
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
import testutil.SymbolAndFunctionCleaner import testutil.SymbolAndFunctionCleaner
import testutil.TestUtilities.evaluateString import testutil.TestUtilities.evaluateString
import java.util.HashSet import java.util.HashSet
@TestInstance(PER_CLASS)
class ExitTest : SymbolAndFunctionCleaner() { class ExitTest : SymbolAndFunctionCleaner() {
companion object { companion object {

View File

@ -1,123 +0,0 @@
package token;
import file.FilePosition;
import org.junit.Before;
import org.junit.Test;
import token.TokenFactory.BadCharacterException;
import token.TokenFactory.EmptyTokenTextException;
import static error.Severity.CRITICAL;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
public class TokenFactoryTest {
private TokenFactory tokenFactory;
private FilePosition testPosition;
@Before
public void setUp() {
tokenFactory = new TokenFactoryImpl();
testPosition = new FilePosition("testFile", 0, 0);
}
private Token createToken(String text) {
return tokenFactory.createToken(text, testPosition);
}
@Test
public void eofTokenCreation() {
assertThat(tokenFactory.createEofToken(testPosition), instanceOf(Eof.class));
}
@Test
public void leftParenthesisCreation() {
String text = "(";
assertThat(createToken(text), instanceOf(LeftParenthesis.class));
}
@Test
public void rightParenthesisCreation() {
String text = ")";
assertThat(createToken(text), instanceOf(RightParenthesis.class));
}
@Test
public void quoteMarkCreation() {
String text = "'";
assertThat(createToken(text), instanceOf(QuoteMark.class));
}
@Test
public void numberCreation() {
String text = "987";
assertThat(createToken(text), instanceOf(Number.class));
}
@Test
public void prefixedNumberCreation() {
String text = "-987";
assertThat(createToken(text), instanceOf(Number.class));
}
@Test
public void identifierCreation() {
String text = "identifier";
assertThat(createToken(text), instanceOf(Identifier.class));
}
@Test
public void prefixedIdentifierCreation() {
String text = "-identifier";
assertThat(createToken(text), instanceOf(Identifier.class));
}
@Test
public void stringCreation() {
String text = "\"string\"";
assertThat(createToken(text), instanceOf(QuotedString.class));
}
@Test(expected = EmptyTokenTextException.class)
public void emptyString_ThrowsException() {
createToken("");
}
@Test
public void emptyTokenTextException_ContainsCorrectAttributes() {
try {
createToken("");
} catch (EmptyTokenTextException e) {
String message = e.getMessage();
assertThat(message, is(notNullValue()));
assertThat(message.length(), greaterThan(0));
assertThat(e.getSeverity(), is(CRITICAL));
}
}
@Test(expected = BadCharacterException.class)
public void badCharacter_ThrowsException() {
createToken("[abc]");
}
@Test
public void backTickCreation() {
String text = "`";
assertThat(createToken(text), instanceOf(Backquote.class));
}
@Test
public void commaCreation() {
String text = ",";
assertThat(createToken(text), instanceOf(Comma.class));
}
@Test
public void atSignCreation() {
String text = "@";
assertThat(createToken(text), instanceOf(AtSign.class));
}
}

View File

@ -0,0 +1,109 @@
package token
import error.Severity.CRITICAL
import file.FilePosition
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertThrows
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 token.TokenFactory.BadCharacterException
import token.TokenFactory.EmptyTokenTextException
@TestInstance(PER_CLASS)
class TokenFactoryTest {
private lateinit var tokenFactory: TokenFactory
private lateinit var testPosition: FilePosition
@BeforeEach
fun setUp() {
tokenFactory = TokenFactoryImpl()
testPosition = FilePosition("testFile", 0, 0)
}
private fun createToken(text: String): Token {
return tokenFactory.createToken(text, testPosition)
}
@Test
fun eofTokenCreation() {
assertThat(tokenFactory.createEofToken(testPosition)).isInstanceOf(Eof::class.java)
}
@Test
fun leftParenthesisCreation() {
assertThat(createToken("(")).isInstanceOf(LeftParenthesis::class.java)
}
@Test
fun rightParenthesisCreation() {
assertThat(createToken(")")).isInstanceOf(RightParenthesis::class.java)
}
@Test
fun quoteMarkCreation() {
assertThat(createToken("'")).isInstanceOf(QuoteMark::class.java)
}
@Test
fun numberCreation() {
assertThat(createToken("987")).isInstanceOf(Number::class.java)
}
@Test
fun prefixedNumberCreation() {
assertThat(createToken("-987")).isInstanceOf(Number::class.java)
}
@Test
fun identifierCreation() {
assertThat(createToken("identifier")).isInstanceOf(Identifier::class.java)
}
@Test
fun prefixedIdentifierCreation() {
assertThat(createToken("-identifier")).isInstanceOf(Identifier::class.java)
}
@Test
fun stringCreation() {
assertThat(createToken("\"string\"")).isInstanceOf(QuotedString::class.java)
}
@Test
fun emptyString_ThrowsException() {
assertThrows(EmptyTokenTextException::class.java) { createToken("") }
}
@Test
fun emptyTokenTextException_ContainsCorrectAttributes() {
try {
createToken("")
} catch (e: EmptyTokenTextException) {
assertThat(e.message).isNotEmpty();
assertThat(e.severity).isEqualTo(CRITICAL)
}
}
@Test
fun badCharacter_ThrowsException() {
assertThrows(BadCharacterException::class.java) { createToken("[abc]") }
}
@Test
fun backTickCreation() {
assertThat(createToken("`")).isInstanceOf(Backquote::class.java)
}
@Test
fun commaCreation() {
assertThat(createToken(",")).isInstanceOf(Comma::class.java)
}
@Test
fun atSignCreation() {
assertThat(createToken("@")).isInstanceOf(AtSign::class.java)
}
}