Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converted to use Kotlin Poet #16

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions annotationprocessor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ buildscript {
repositories{
jcenter()
}
dependencies {
classpath 'com.squareup:javapoet:1.9.0'
}
}

group='com.github.quarkworks' // jitpack.io
Expand All @@ -19,15 +16,15 @@ def source_GIT_COMMIT = new File(buildDir, 'generated/source/GIT_COMMIT/main/jav
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

implementation project(':annotations')
implementation "io.realm:realm-annotations:$realm_version"

kapt "com.google.auto.service:auto-service:1.0-rc2" // don't update yet, won't auto generate code
compileOnly "com.google.auto.service:auto-service:1.0-rc2" // don't update yet, won't auto generate code
kapt "com.google.auto.service:auto-service:1.0-rc4"
compileOnly "com.google.auto.service:auto-service:1.0-rc4"

implementation 'com.squareup:javapoet:1.9.0'
implementation 'com.squareup:kotlinpoet:1.0.0-RC1'
}

repositories {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import com.quarkworks.android.realmtypesafequery.annotations.SkipGenerationOfRea
import com.quarkworks.android.realmtypesafequery.annotations.SkipGenerationOfRealmField
import com.quarkworks.android.realmtypesafequery.annotations.GenerateRealmFieldNames
import com.quarkworks.android.realmtypesafequery.annotations.GenerateRealmFields
import com.squareup.javapoet.FieldSpec
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeName
import com.squareup.javapoet.TypeSpec
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterizedTypeName
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.asTypeName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy

import java.io.IOException
import java.util.LinkedList
Expand All @@ -33,18 +35,25 @@ import javax.tools.Diagnostic
import io.realm.annotations.Ignore
import io.realm.annotations.Index
import io.realm.annotations.PrimaryKey
import javax.annotation.processing.SupportedOptions
import javax.tools.StandardLocation


@AutoService(Processor::class)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedOptions(AnnotationProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME)
class AnnotationProcessor : AbstractProcessor() {

companion object {
const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"
}

private fun String.toConstId() : String = this.replace("([a-z])([A-Z])".toRegex(), "$1_$2").toUpperCase()

private fun Element.isAnnotatedWith(annotation: Class<out Annotation>) : Boolean =
this.getAnnotation(annotation) != null

private val fieldSpecsModifiers = arrayOf(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
private val propertySpecsModifiers = arrayOf(KModifier.PUBLIC)
private val packageName: String = "com.quarkworks.android.realmtypesafequery" + ".generated"
private val supportedAnnotationTypes: Set<String> = setOf(
GenerateRealmFieldNames::class.java.canonicalName,
Expand Down Expand Up @@ -80,7 +89,7 @@ class AnnotationProcessor : AbstractProcessor() {
if (element !is TypeElement) continue

val variableElements = ElementFilter.fieldsIn(element.enclosedElements)
val fieldSpecs = LinkedList<FieldSpec>()
val propertySpecs = LinkedList<PropertySpec>()

for (realmField in variableElements) {
// ignore static and @Ignore fields
Expand All @@ -90,29 +99,35 @@ class AnnotationProcessor : AbstractProcessor() {

val name = realmField.simpleName.toString().toConstId()

val fieldSpec = FieldSpec.builder(String::class.java, name, *fieldSpecsModifiers)
.initializer("\$S", realmField.simpleName)
val propertySpec = PropertySpec.builder(name, String::class, KModifier.CONST, *propertySpecsModifiers)
.initializer("%S", realmField.simpleName)
.build()

fieldSpecs.add(fieldSpec)
propertySpecs.add(propertySpec)
}

val className = element.simpleName.toString() + "FieldNames"

val typeSpec = TypeSpec.classBuilder(className).addFields(fieldSpecs)
.addModifiers(Modifier.PUBLIC).build()
val typeSpec = TypeSpec.objectBuilder(className).addProperties(propertySpecs)
.build()

val javaFile = JavaFile.builder(packageName, typeSpec).build()
val kotlinFile = FileSpec.builder(packageName, className)
.addType(typeSpec)
.build()

try {
javaFile.writeTo(this.processingEnv.filer)
val kotlinFileObject = processingEnv.filer.createResource(StandardLocation.SOURCE_OUTPUT,
packageName, "$className.kt")
val writer = kotlinFileObject.openWriter()
kotlinFile.writeTo(writer)
writer.close()
} catch (e: IOException) {
this.reportError(element, e.toString())
}
}
}

private fun makeFieldSpec(realmClassElement: Element, realmFieldElement: Element): FieldSpec {
private fun makePropertySpec(realmClassElement: Element, realmFieldElement: Element): PropertySpec {

if (typeUtils.isSubtype(realmFieldElement.asType(), realmModel)) {
return makeToOne(realmClassElement, realmFieldElement)
Expand All @@ -125,45 +140,48 @@ class AnnotationProcessor : AbstractProcessor() {

val isPrimaryKey = realmFieldElement.isAnnotatedWith(PrimaryKey::class.java)
val isIndex = realmFieldElement.isAnnotatedWith(Index::class.java)
val typeName = TypeName.get(realmClassElement.asType())
val typeName = realmClassElement.asType().asTypeName()
val parameterizedTypeName: ParameterizedTypeName

parameterizedTypeName = if (!isPrimaryKey && !isIndex) {
ParameterizedTypeName.get(Maps.BASE_MAP[rfeClass], typeName)
Maps.BASE_MAP[rfeClass]!!.parameterizedBy(typeName)
} else {
ParameterizedTypeName.get(Maps.INDEX_MAP[Maps.BASE_MAP[rfeClass]], typeName)
Maps.INDEX_MAP[Maps.BASE_MAP[rfeClass]]!!.parameterizedBy(typeName)
}

return FieldSpec.builder(parameterizedTypeName, fieldName.toConstId(), *fieldSpecsModifiers)
.initializer("new \$T(\$T.class, \$S)", parameterizedTypeName, typeName, fieldName)
.build()
return PropertySpec.builder(fieldName.toConstId(), parameterizedTypeName, *propertySpecsModifiers)
.initializer("%T(%T::class.java, %S)", parameterizedTypeName, typeName, fieldName)
.addAnnotation(JvmField::class)
.build()
}

private fun makeToMany(realmClassElement: Element, realmFieldElement: Element): FieldSpec {
private fun makeToMany(realmClassElement: Element, realmFieldElement: Element): PropertySpec {
val typeMirror = realmClassElement.asType()
val fieldName = realmFieldElement.simpleName.toString()

val parameterizedTypeName = ParameterizedTypeName.get(Maps.REALM_TO_MANY_RELATIONSHIP,
TypeName.get(typeMirror),
TypeName.get((realmFieldElement.asType() as DeclaredType).typeArguments[0]))
val parameterizedTypeName = Maps.REALM_TO_MANY_RELATIONSHIP.parameterizedBy(
typeMirror.asTypeName(),
(realmFieldElement.asType() as DeclaredType).typeArguments[0].asTypeName())

return FieldSpec.builder(parameterizedTypeName, fieldName.toConstId(), *fieldSpecsModifiers)
.initializer("new \$T(\$T.class, \$S)", parameterizedTypeName, TypeName.get(typeMirror), fieldName)
.build()
return PropertySpec.builder(fieldName.toConstId(), parameterizedTypeName, *propertySpecsModifiers)
.initializer("%T(%T::class.java, %S)", parameterizedTypeName, typeMirror.asTypeName(), fieldName)
.addAnnotation(JvmField::class)
.build()

}

private fun makeToOne(realmClassElement: Element, realmFieldElement: Element): FieldSpec {
private fun makeToOne(realmClassElement: Element, realmFieldElement: Element): PropertySpec {
val typeMirror = realmClassElement.asType()
val fieldName = realmFieldElement.simpleName.toString()

val parameterizedTypeName = ParameterizedTypeName.get(Maps.REALM_TO_ONE_RELATIONSHIP,
TypeName.get(typeMirror),
TypeName.get(realmFieldElement.asType()))
val parameterizedTypeName = Maps.REALM_TO_ONE_RELATIONSHIP.parameterizedBy(
typeMirror.asTypeName(),
realmFieldElement.asType().asTypeName())

return FieldSpec.builder(parameterizedTypeName, fieldName.toConstId(), *fieldSpecsModifiers)
.initializer("new \$T(\$T.class, \$S)", parameterizedTypeName, TypeName.get(typeMirror), fieldName)
.build()
return PropertySpec.builder(fieldName.toConstId(), parameterizedTypeName, *propertySpecsModifiers)
.initializer("%T(%T::class.java, %S)", parameterizedTypeName, typeMirror.asTypeName(), fieldName)
.addAnnotation(JvmField::class)
.build()

}

Expand All @@ -172,27 +190,32 @@ class AnnotationProcessor : AbstractProcessor() {
if (element !is TypeElement) continue

val variableElements = ElementFilter.fieldsIn(element.enclosedElements)
val fieldSpecs = LinkedList<FieldSpec>()
val propertySpecs = LinkedList<PropertySpec>()

for (realmField in variableElements) {
if (realmField.modifiers.contains(Modifier.STATIC)) continue
if (realmField.isAnnotatedWith(Ignore::class.java)) continue
if (realmField.isAnnotatedWith(SkipGenerationOfRealmField::class.java)) continue

fieldSpecs.add(makeFieldSpec(element, realmField))
propertySpecs.add(makePropertySpec(element, realmField))
}

val className = element.simpleName.toString() + "Fields"

val typeSpec = TypeSpec.classBuilder(className)
.addFields(fieldSpecs)
.addModifiers(Modifier.PUBLIC)
val typeSpec = TypeSpec.objectBuilder(className)
.addProperties(propertySpecs)
.addModifiers(KModifier.PUBLIC)
.build()

val javaFile = JavaFile.builder(packageName, typeSpec).build()
val kotlinFile = FileSpec.builder(packageName, className)
.addType(typeSpec)
.build()

try {
javaFile.writeTo(this.processingEnv.filer)
val kotlinFileObject = processingEnv.filer.createResource(StandardLocation.SOURCE_OUTPUT, packageName, "$className.kt")
val writer = kotlinFileObject.openWriter()
kotlinFile.writeTo(writer)
writer.close()
} catch (e: IOException) {
this.reportError(element, e.toString())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.quarkworks.android.realmtypesafequery.annotationprocessor

import com.squareup.javapoet.ClassName
import com.squareup.kotlinpoet.ClassName

import java.util.HashMap

internal object Maps {
val BASE_MAP = HashMap<String, ClassName>()
val INDEX_MAP = HashMap<ClassName, ClassName>()

private val PACKAGE = "com.quarkworks.android.realmtypesafequery.fields"
private const val PACKAGE = "com.quarkworks.android.realmtypesafequery.fields"

private fun getClassName(simpleName: String) : ClassName = ClassName.get(PACKAGE, simpleName)!!
private fun getClassName(simpleName: String) : ClassName = ClassName(PACKAGE, simpleName)

private val REALM_BOOLEAN_FIELD = getClassName("RealmBooleanField")
private val REALM_BYTE_FIELD = getClassName("RealmByteField")
Expand All @@ -35,31 +35,31 @@ internal object Maps {
val REALM_TO_MANY_RELATIONSHIP = getClassName("RealmToManyRelationship")

init {
BASE_MAP.put("java.lang.Boolean", REALM_BOOLEAN_FIELD)
BASE_MAP.put("java.lang.Byte", REALM_BYTE_FIELD)
BASE_MAP.put("java.lang.Short", REALM_SHORT_FIELD)
BASE_MAP.put("java.lang.Integer", REALM_INTEGER_FIELD)
BASE_MAP.put("java.lang.Long", REALM_LONG_FIELD)
BASE_MAP.put("java.lang.Float", REALM_FLOAT_FIELD)
BASE_MAP.put("java.lang.Double", REALM_DOUBLE_FIELD)
BASE_MAP.put("java.lang.String", REALM_STRING_FIELD)
BASE_MAP.put("java.util.Date", REALM_DATE_FIELD)
BASE_MAP["java.lang.Boolean"] = REALM_BOOLEAN_FIELD
BASE_MAP["java.lang.Byte"] = REALM_BYTE_FIELD
BASE_MAP["java.lang.Short"] = REALM_SHORT_FIELD
BASE_MAP["java.lang.Integer"] = REALM_INTEGER_FIELD
BASE_MAP["java.lang.Long"] = REALM_LONG_FIELD
BASE_MAP["java.lang.Float"] = REALM_FLOAT_FIELD
BASE_MAP["java.lang.Double"] = REALM_DOUBLE_FIELD
BASE_MAP["java.lang.String"] = REALM_STRING_FIELD
BASE_MAP["java.util.Date"] = REALM_DATE_FIELD

BASE_MAP.put("boolean", REALM_BOOLEAN_FIELD)
BASE_MAP.put("byte", REALM_BYTE_FIELD)
BASE_MAP.put("byte[]", REALM_BYTE_ARRAY_FIELD)
BASE_MAP.put("short", REALM_SHORT_FIELD)
BASE_MAP.put("int", REALM_INTEGER_FIELD)
BASE_MAP.put("long", REALM_LONG_FIELD)
BASE_MAP.put("float", REALM_FLOAT_FIELD)
BASE_MAP.put("double", REALM_DOUBLE_FIELD)
BASE_MAP["boolean"] = REALM_BOOLEAN_FIELD
BASE_MAP["byte"] = REALM_BYTE_FIELD
BASE_MAP["byte[]"] = REALM_BYTE_ARRAY_FIELD
BASE_MAP["short"] = REALM_SHORT_FIELD
BASE_MAP["int"] = REALM_INTEGER_FIELD
BASE_MAP["long"] = REALM_LONG_FIELD
BASE_MAP["float"] = REALM_FLOAT_FIELD
BASE_MAP["double"] = REALM_DOUBLE_FIELD

INDEX_MAP.put(REALM_BOOLEAN_FIELD, REALM_INDEXED_BOOLEAN_FIELD)
INDEX_MAP.put(REALM_BYTE_FIELD, REALM_INDEXED_BYTE_FIELD)
INDEX_MAP.put(REALM_SHORT_FIELD, REALM_INDEXED_SHORT_FIELD)
INDEX_MAP.put(REALM_INTEGER_FIELD, REALM_INDEXED_INTEGER_FIELD)
INDEX_MAP.put(REALM_LONG_FIELD, REALM_INDEXED_LONG_FIELD)
INDEX_MAP.put(REALM_STRING_FIELD, REALM_INDEXED_STRING_FIELD)
INDEX_MAP.put(REALM_DATE_FIELD, REALM_INDEXED_DATE_FIELD)
INDEX_MAP[REALM_BOOLEAN_FIELD] = REALM_INDEXED_BOOLEAN_FIELD
INDEX_MAP[REALM_BYTE_FIELD] = REALM_INDEXED_BYTE_FIELD
INDEX_MAP[REALM_SHORT_FIELD] = REALM_INDEXED_SHORT_FIELD
INDEX_MAP[REALM_INTEGER_FIELD] = REALM_INDEXED_INTEGER_FIELD
INDEX_MAP[REALM_LONG_FIELD] = REALM_INDEXED_LONG_FIELD
INDEX_MAP[REALM_STRING_FIELD] = REALM_INDEXED_STRING_FIELD
INDEX_MAP[REALM_DATE_FIELD] = REALM_INDEXED_DATE_FIELD
}
}
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.2.20'
ext.realm_version = '5.0.1'
ext.kotlin_version = '1.2.60'
ext.realm_version = '5.4.2'
ext.sdk_version = 25
ext.build_tools_version = '27.0.3'
ext.support_library_version = '25.1.1'
Expand All @@ -13,7 +13,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.1.0'
classpath 'com.android.tools.build:gradle:3.1.4'
//noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "io.realm:realm-gradle-plugin:$realm_version"
Expand Down
4 changes: 3 additions & 1 deletion example_javaOnly/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'

android {
Expand Down Expand Up @@ -26,5 +28,5 @@ dependencies {
implementation "com.android.support:appcompat-v7:$support_library_version"
implementation project(':query')
implementation project(':annotations')
annotationProcessor project(':annotationprocessor')
kapt project(':annotationprocessor')
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MainActivityKotlincallMix : AppCompatActivity() {

Realm.init(this.applicationContext)

Realm.getDefaultInstance().use({ realm ->
Realm.getDefaultInstance().use { realm ->

realm.executeTransaction { realm ->
realm.deleteAll()
Expand Down Expand Up @@ -50,7 +50,7 @@ class MainActivityKotlincallMix : AppCompatActivity() {
Log.d(TAG, "TestRecordJava Equal To null: " + RealmTypeSafeQuery.with(realm).where(TestRecordJava::class.java).equalTo(TestRecordJavaFields.STRING_FIELD, null).findAll().toString())
Log.d(TAG, "TestRecordJava IsNull: " + RealmTypeSafeQuery.with(realm).where(TestRecordJava::class.java).isNull(TestRecordJavaFields.STRING_FIELD).findAll().toString())
Log.d(TAG, "TestRecordJava IsNotNull: " + RealmTypeSafeQuery.with(realm).where(TestRecordJava::class.java).isNotNull(TestRecordJavaFields.STRING_FIELD).findAll().toString())
})
}
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class MainActivity : AppCompatActivity() {
val config = RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build()
Realm.setDefaultConfiguration(config)

Realm.getDefaultInstance().use({ realm ->
Realm.getDefaultInstance().use { realm ->

realm.executeTransaction { realm ->
realm.deleteAll()
Expand Down Expand Up @@ -57,7 +57,7 @@ class MainActivity : AppCompatActivity() {
Log.d(TAG, "Equal To null: " + RealmTypeSafeQuery.with(realm).where(TestRecord::class.java).equalTo(TestRecordFields.STRING_FIELD, null).findAll().toString())
Log.d(TAG, "IsNull: " + RealmTypeSafeQuery.with(realm).where(TestRecord::class.java).isNull(TestRecordFields.STRING_FIELD).findAll().toString())
Log.d(TAG, "IsNotNull: " + RealmTypeSafeQuery.with(realm).where(TestRecord::class.java).isNotNull(TestRecordFields.STRING_FIELD).findAll().toString())
})
}
}

companion object {
Expand Down
2 changes: 1 addition & 1 deletion query/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ android {

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compileOnly "com.android.support:support-annotations:$support_library_version"
compileOnly "io.realm:realm-android-library:$realm_version"
}
Expand Down