Allow int literals for consts of type double (#195)

This commit is contained in:
Ben Bader 2018-07-31 15:54:05 -07:00 коммит произвёл GitHub
Родитель 0b5c3e9cb4
Коммит 3d33badd83
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 70 добавлений и 9 удалений

Просмотреть файл

@ -43,6 +43,8 @@ enum Numberz
EIGHT = 8
}
const double ActualDouble = 42
const Numberz myNumberz = Numberz.ONE;
// the following is expected to fail:
// const Numberz urNumberz = ONE;

Просмотреть файл

@ -39,7 +39,7 @@ uploadArchives.enabled = false
sourceSets {
test {
java.srcDirs += ['build/generated-src/thrifty']
java.srcDirs += ['build/generated-src/thrifty/java', 'build/generated-src/thrifty/kotlin']
}
}
@ -54,19 +54,26 @@ mainClassName = 'com.microsoft.thrifty.compiler.ThriftyCompiler'
task compileTestThrift(type: Exec) {
def jarTask = project.tasks['shadowJar'] as Jar
inputs.file("$projectDir/ClientThriftTest.thrift")
outputs.dir("$projectDir/build/generated-src/thrifty/java")
dependsOn jarTask
executable 'java'
args = ['-jar', jarTask.archivePath.absolutePath, "--out=$projectDir/build/generated-src/thrifty", "$projectDir/ClientThriftTest.thrift"]
args = ['-jar', jarTask.archivePath.absolutePath, "--out=$projectDir/build/generated-src/thrifty/java", "$projectDir/ClientThriftTest.thrift"]
}
task kompileTestThrift(type: Exec) {
def jarTask = project.tasks['shadowJar'] as Jar
inputs.file("$projectDir/ClientThriftTest.thrift")
outputs.dir("$projectDir/build/generated-src/thrifty/kotlin")
dependsOn jarTask
executable 'java'
args = ['-jar', jarTask.archivePath.absolutePath, "--out=$projectDir/build/generated-src/thrifty", "--kotlin", "$projectDir/ClientThriftTest.thrift"]
args = ['-jar', jarTask.archivePath.absolutePath, "--out=$projectDir/build/generated-src/thrifty/kotlin", "--kotlin", "$projectDir/ClientThriftTest.thrift"]
}
compileTestKotlin {
@ -74,6 +81,14 @@ compileTestKotlin {
dependsOn kompileTestThrift
}
task cleanTestCode(type: Delete) {
delete "$projectDir/build/generated-src/thrifty"
}
clean {
dependsOn cleanTestCode
}
compileTestJava {
dependsOn compileTestThrift
dependsOn kompileTestThrift

Просмотреть файл

@ -951,7 +951,7 @@ class KotlinCodeGenerator(
}
override fun visitDouble(doubleType: BuiltinType) {
if (value.isDouble) {
if (value.isDouble || value.isInt) {
block.add("%L", value.getAsDouble())
} else {
constOrError("Invalid double constant")

Просмотреть файл

@ -106,12 +106,12 @@ class Constant internal constructor (
}
private object Validators {
private val BOOL = BoolValidator()
private val BOOL = BoolValidator
private val BYTE = IntegerValidator(java.lang.Byte.MIN_VALUE.toLong(), java.lang.Byte.MAX_VALUE.toLong())
private val I16 = IntegerValidator(java.lang.Short.MIN_VALUE.toLong(), java.lang.Short.MAX_VALUE.toLong())
private val I32 = IntegerValidator(Integer.MIN_VALUE.toLong(), Integer.MAX_VALUE.toLong())
private val I64 = IntegerValidator(java.lang.Long.MIN_VALUE, java.lang.Long.MAX_VALUE)
private val DOUBLE = BaseValidator(ConstValueElement.Kind.DOUBLE)
private val DOUBLE = DoubleValidator
private val STRING = BaseValidator(ConstValueElement.Kind.STRING)
private val ENUM = EnumValidator()
@ -157,7 +157,7 @@ class Constant internal constructor (
}
}
private class BoolValidator : ConstValueValidator {
private object BoolValidator : ConstValueValidator {
override fun validate(symbolTable: SymbolTable, expected: ThriftType, value: ConstValueElement) {
if (value.kind === ConstValueElement.Kind.INTEGER) {
val n = value.getAsInt()
@ -221,6 +221,27 @@ class Constant internal constructor (
}
}
private object DoubleValidator : ConstValueValidator {
override fun validate(symbolTable: SymbolTable, expected: ThriftType, value: ConstValueElement) {
if (value.isInt || value.isDouble) {
// valid
} else if (value.isIdentifier) {
// maybe a const?
val id = value.value as String
val constant = symbolTable.lookupConst(id)
?: throw IllegalStateException("Unrecognized const identifier: $id")
if (constant.type().trueType != expected) {
throw IllegalStateException("Expected a value of type " + expected.name
+ ", but got " + constant.type().name)
}
} else {
throw IllegalStateException(
"Expected a value of type DOUBLE but got " + value.value)
}
}
}
private class EnumValidator : ConstValueValidator {
override fun validate(symbolTable: SymbolTable, expected: ThriftType, value: ConstValueElement) {
if (!expected.isEnum) {

Просмотреть файл

@ -87,8 +87,12 @@ data class ConstValueElement(
}
fun getAsDouble(): Double {
check(isDouble) { "Cannot convert to double; kind=$kind" }
return value as Double
check(isInt || isDouble) { "Cannot convert to double; kind=$kind" }
return when {
isDouble -> value as Double
isInt -> getAsInt().toDouble()
else -> error("unpossible")
}
}
fun getAsString(): String {

Просмотреть файл

@ -1019,6 +1019,15 @@ class LoaderTest {
}
}
@Test
fun constDoubleWithIntLiteral() {
val thrift = """
const double FOO = 2
""".trimIndent()
load(thrift)
}
private fun load(thrift: String): Schema {
val f = tempDir.newFile()
f.writeText(thrift)

Просмотреть файл

@ -1224,6 +1224,16 @@ class ThriftParserTest {
assertThat(documentation, isEmptyString())
}
@Test
fun `double-valued consts can have integer literal values`() {
val thrift = """
const double foo = 2
""".trimIndent()
val constants = parse(thrift).constants
assertThat(constants.single().value.getAsDouble(), equalTo(2.0))
}
companion object {
private val TEST_UUID = UUID.fromString("ecafa042-668a-4403-a6d3-70983866ffbe")