Skip to content

Commit

Permalink
add Enum support
Browse files Browse the repository at this point in the history
  • Loading branch information
sgpublic committed Oct 11, 2022
1 parent f6eceee commit 07bbc0d
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
import javax.lang.model.type.DeclaredType
import javax.lang.model.type.TypeMirror
import javax.tools.Diagnostic

object ConverterCompiler {
private val converters: HashMap<String, TypeElement> = hashMapOf()
Expand Down Expand Up @@ -98,13 +97,11 @@ object ConverterCompiler {

val static = CodeBlock.builder()
for (element: Element in env.getElementsAnnotatedWith(ExConverter::class.java)) {
ExPreferenceProcessor.mMessager.printMessage(Diagnostic.Kind.WARNING, "element: ${element.javaClass}")
if (element !is TypeElement) {
continue
}
val typeParam = findTargetType(element)
val name = (typeParam.first.asElement() as TypeElement).qualifiedName.toString()
ExPreferenceProcessor.mMessager.printMessage(Diagnostic.Kind.WARNING, "name: $name")
targets[name] = typeParam.second.asElement() as TypeElement
converters[name] = element
static.addStatement("\$T.registry.put(\$T.class, \$T.class)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import com.squareup.javapoet.*
import io.github.sgpublic.exsp.ExPreferenceProcessor
import io.github.sgpublic.exsp.annotations.ExSharedPreference
import io.github.sgpublic.exsp.annotations.ExValue
import io.github.sgpublic.exsp.util.SharedPreferenceType
import io.github.sgpublic.exsp.util.getterName
import io.github.sgpublic.exsp.util.setterName
import io.github.sgpublic.exsp.util.supported
import io.github.sgpublic.exsp.util.*
import java.util.*
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.Element
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
import javax.lang.model.element.VariableElement
import javax.tools.Diagnostic

object PreferenceCompiler {
fun apply(env: RoundEnvironment) {
Expand Down Expand Up @@ -87,7 +85,7 @@ object PreferenceCompiler {
if (field.modifiers.contains(Modifier.FINAL)) {
continue
}
val type = ClassName.get(field.asType())
val type: TypeName = ClassName.get(field.asType())

val name = field.getAnnotation(ExValue::class.java).key.takeIf { it != "" }
?: field.simpleName.toString().replaceFirstChar {
Expand All @@ -109,9 +107,14 @@ object PreferenceCompiler {


var convertedType = type
ExPreferenceProcessor.mMessager.printMessage(Diagnostic.Kind.WARNING, "field: ${field.asType()}")
if (type.supported()) {
setter.addStatement("\$T converted = value", type)
getter.addStatement("\$T origin", type)
} else if (field.isEnum()) {
convertedType = StringTypeOrigin
setter.addStatement("\$T converted = value.name()", convertedType)
getter.addStatement("\$T origin", convertedType)
} else {
val convertedElement = ConverterCompiler.getTarget(ExPreferenceProcessor.asElement(field.asType())!!)
setter.addStatement("\$T converted = \$T.toPreference(\$T.class, value)",
Expand All @@ -120,34 +123,47 @@ object PreferenceCompiler {
getter.addStatement("\$T origin", convertedType)
}

when (SharedPreferenceType.of(convertedType)) {
SharedPreferenceType.BOOLEAN -> {
getter.addStatement("origin = sp.getBoolean($conf, $defVal)")
setter.addStatement("editor.putBoolean($conf, converted)")
}
SharedPreferenceType.INT -> {
getter.addStatement("origin = sp.getInt($conf, $defVal)")
setter.addStatement("editor.putInt($conf, converted)")
}
SharedPreferenceType.LONG -> {
getter.addStatement("origin = sp.getLong($conf, $defVal)")
setter.addStatement("editor.putLong($conf, converted)")
try {
when (SharedPreferenceType.of(convertedType)) {
SharedPreferenceType.BOOLEAN -> {
getter.addStatement("origin = sp.getBoolean($conf, $defVal)")
setter.addStatement("editor.putBoolean($conf, converted)")
}
SharedPreferenceType.INT -> {
getter.addStatement("origin = sp.getInt($conf, $defVal)")
setter.addStatement("editor.putInt($conf, converted)")
}
SharedPreferenceType.LONG -> {
getter.addStatement("origin = sp.getLong($conf, $defVal)")
setter.addStatement("editor.putLong($conf, converted)")
}
SharedPreferenceType.FLOAT -> {
getter.addStatement("origin = sp.getFloat($conf, $defVal)")
setter.addStatement("editor.putFloat($conf, value)")
}
SharedPreferenceType.STRING -> {
getter.addStatement("origin = sp.getString($conf, \"$defVal\")")
setter.addStatement("editor.putString($conf, converted)")
}
SharedPreferenceType.STRING_SET -> {
getter.addStatement("origin = sp.getStringSet($conf, \"$defVal\")")
setter.addStatement("editor.putStringSet($conf, converted)")
}
}
SharedPreferenceType.FLOAT -> {
getter.addStatement("origin = sp.getFloat($conf, $defVal)")
setter.addStatement("editor.putFloat($conf, value)")
}
SharedPreferenceType.STRING -> {
getter.addStatement("origin = sp.getString($conf, \"$defVal\")")
setter.addStatement("editor.putString($conf, converted)")
}
SharedPreferenceType.STRING_SET -> {
getter.addStatement("origin = sp.getStringSet($conf, \"$defVal\")")
setter.addStatement("editor.putStringSet($conf, converted)")
} catch (e: Exception) {
if (!field.isEnum()) {
throw e
}
}

if (type.supported()) {
getter.addStatement("return origin")
} else if (field.isEnum()) {
getter.beginControlFlow("try")
getter.addStatement("return \$T.valueOf(origin)", type)
getter.nextControlFlow("catch (\$T ignore)", IllegalArgumentException::class.java)
getter.addStatement("return \$T.valueOf(\"$defVal\")", type)
getter.endControlFlow()
} else {
getter.addStatement("return \$T.fromPreference(\$T.class, origin)",
ExPreferenceProcessor.ExConverters, type)
Expand Down
23 changes: 21 additions & 2 deletions compiler/src/main/kotlin/io/github/sgpublic/exsp/util/_Types.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package io.github.sgpublic.exsp.util
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeName
import io.github.sgpublic.exsp.ExPreferenceProcessor
import java.util.*
import javax.lang.model.element.VariableElement
import javax.tools.Diagnostic

fun HashSet<TypeName>.andBoxed(): HashSet<TypeName> {
val set = HashSet<TypeName>()
Expand All @@ -23,8 +25,8 @@ fun HashSet<TypeName>.andString(): HashSet<TypeName> {
return this
}

private val StringTypeOrigin: TypeName = ClassName.get("java.lang", "String")
private val StringTypeSetOrigin: TypeName = ParameterizedTypeName.get(Set::class.java, String::class.java)
val StringTypeOrigin: ClassName = ClassName.get("java.lang", "String")
val StringTypeSetOrigin: TypeName = ParameterizedTypeName.get(Set::class.java, String::class.java)

private val BooleanType = hashSetOf(
ClassName.BOOLEAN
Expand Down Expand Up @@ -75,6 +77,23 @@ fun VariableElement.setterName(): String {
return "set$name"
}

private val obj = ExPreferenceProcessor.getElement("java.lang.Object")
private val enu = ExPreferenceProcessor.getElement("java.lang.Enum")
fun VariableElement.isEnum(): Boolean {
var asElement = ExPreferenceProcessor.asElement(asType()) ?: return false
while (asElement.superclass != null) {
ExPreferenceProcessor.mMessager.printMessage(Diagnostic.Kind.WARNING, "asElement: $asElement")
if (asElement == enu) {
return true
}
if (asElement == obj) {
break
}
asElement = ExPreferenceProcessor.asElement(asElement.superclass) ?: break
}
return false
}

enum class SharedPreferenceType {
BOOLEAN, INT, LONG, FLOAT, STRING, STRING_SET;

Expand Down
13 changes: 13 additions & 0 deletions demo/src/main/java/io/github/sgpublic/exsp/demo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.github.sgpublic.exsp.demo
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.RadioButton
import android.widget.Switch
import androidx.appcompat.app.AppCompatActivity
import io.github.sgpublic.exsp.ExPreference
Expand All @@ -17,6 +18,8 @@ class MainActivity : AppCompatActivity() {
private lateinit var mdate: EditText
private lateinit var mfloat: EditText
private lateinit var mbool: Switch
private lateinit var mtypea: RadioButton
private lateinit var mtypeb: RadioButton

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -31,6 +34,10 @@ class MainActivity : AppCompatActivity() {
test.testLong = mlong.text.toString().toLong()
test.isTestBool = mbool.isChecked
test.testDate = SimpleDateFormat("yyyy.MM.dd").parse(mdate.text.toString())
when {
mtypea.isChecked -> test.testEnum = TestPreference.Type.TYPE_A
mtypeb.isChecked -> test.testEnum = TestPreference.Type.TYPE_B
}
}
}

Expand All @@ -41,6 +48,8 @@ class MainActivity : AppCompatActivity() {
mfloat = findViewById(R.id.mfloat)
mbool = findViewById(R.id.mbool)
mdate = findViewById(R.id.mdate)
mtypea = findViewById(R.id.mtypea)
mtypeb = findViewById(R.id.mtypeb)
}

private fun onViewSetup() {
Expand All @@ -50,5 +59,9 @@ class MainActivity : AppCompatActivity() {
mfloat.setText(test.testFloat.toString())
mbool.isChecked = test.isTestBool
mdate.setText(SimpleDateFormat("yyyy.MM.dd").format(test.testDate))
when (test.testEnum) {
TestPreference.Type.TYPE_A -> mtypea.isChecked = true
TestPreference.Type.TYPE_B -> mtypeb.isChecked = true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,11 @@ public class TestPreference {

@ExValue(defVal = "-1")
private Date testDate;

@ExValue(defVal = "TYPE_A")
private Type testEnum;

public enum Type {
TYPE_A, TYPE_B
}
}
17 changes: 16 additions & 1 deletion demo/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,25 @@
android:layout_height="wrap_content"
android:text="switch to change preference" />

<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/mtypea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TYPE_A"/>
<RadioButton
android:id="@+id/mtypeb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TYPE_B"/>
</RadioGroup>

<Button
android:id="@+id/msave"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="save" />

</LinearLayout>
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
android.nonTransitiveRClass=true

exsp.version=1.0.0-alpha03
exsp.version=1.0.0-alpha04

0 comments on commit 07bbc0d

Please sign in to comment.