diff --git a/build.gradle b/build.gradle index 5f963b2..b7ad15c 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ allprojects { } } -project.ext.set("publishVersion", "0.1.0") +project.ext.set("publishVersion", "0.2.0") task clean(type: Delete) { delete rootProject.buildDir diff --git a/compiler/build.gradle b/compiler/build.gradle index 6047835..afe01ea 100644 --- a/compiler/build.gradle +++ b/compiler/build.gradle @@ -41,14 +41,6 @@ dependencies { implementation "com.google.auto.service:auto-service:1.0-rc6" kapt "com.google.auto.service:auto-service:1.0-rc6" - def dagger = "2.25.2" - implementation "com.google.dagger:dagger:$dagger" - kapt "com.google.dagger:dagger-compiler:$dagger" - - def assistedInject = '0.5.2' - compileOnly "com.squareup.inject:assisted-inject-annotations-dagger2:$assistedInject" - kapt "com.squareup.inject:assisted-inject-processor-dagger2:$assistedInject" - def incap = "0.2" compileOnly "net.ltgt.gradle.incap:incap:$incap" kapt "net.ltgt.gradle.incap:incap-processor:$incap" diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/BunchProcessor.kt b/compiler/src/main/java/com/tompee/bunch/compiler/BunchProcessor.kt index 1d9ddd8..7cabf60 100644 --- a/compiler/src/main/java/com/tompee/bunch/compiler/BunchProcessor.kt +++ b/compiler/src/main/java/com/tompee/bunch/compiler/BunchProcessor.kt @@ -1,52 +1,51 @@ package com.tompee.bunch.compiler +import com.google.auto.common.BasicAnnotationProcessor import com.google.auto.service.AutoService +import com.google.common.collect.ImmutableList import com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview -import com.tompee.bunch.annotation.Bunch -import com.tompee.bunch.compiler.di.AppComponent -import com.tompee.bunch.compiler.di.DaggerAppComponent -import com.tompee.bunch.compiler.generators.BunchGenerator import net.ltgt.gradle.incap.IncrementalAnnotationProcessor import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType -import javax.annotation.processing.* -import javax.inject.Inject +import javax.annotation.processing.Processor +import javax.annotation.processing.SupportedOptions +import javax.annotation.processing.SupportedSourceVersion import javax.lang.model.SourceVersion -import javax.lang.model.element.TypeElement -import javax.tools.Diagnostic @AutoService(Processor::class) @SupportedSourceVersion(SourceVersion.RELEASE_8) @SupportedOptions(BunchProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME) @IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING) @KotlinPoetMetadataPreview -internal class BunchProcessor : AbstractProcessor() { - - private lateinit var appComponent: AppComponent - - @Inject - lateinit var generatorFactory: BunchGenerator.Factory +internal class BunchProcessor : BasicAnnotationProcessor() { companion object { const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated" } - override fun getSupportedAnnotationTypes(): MutableSet { - return mutableSetOf(Bunch::class.java.name) - } - override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest() - override fun process(set: MutableSet?, env: RoundEnvironment?): Boolean { - appComponent = DaggerAppComponent.factory().create(processingEnv) - appComponent.inject(this) - - env?.getElementsAnnotatedWith(Bunch::class.java)?.forEach { - try { - generatorFactory.create(it).generate() - } catch (e: ProcessorException) { - processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, e.message, e.element) - } - } - return true + override fun initSteps(): MutableIterable { + return ImmutableList.of( + GeneratorStep( + processingEnv.elementUtils, + processingEnv.typeUtils, + processingEnv.messager, + processingEnv.filer + ) + ) } + +// override fun process(set: MutableSet?, env: RoundEnvironment?): Boolean { +// appComponent = DaggerAppComponent.factory().create(processingEnv) +// appComponent.inject(this) +// +// env?.getElementsAnnotatedWith(Bunch::class.java)?.forEach { +// try { +// generatorFactory.create(it).generate() +// } catch (e: ProcessorException) { +// processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, e.message, e.element) +// } +// } +// return true +// } } \ No newline at end of file diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/GeneratorStep.kt b/compiler/src/main/java/com/tompee/bunch/compiler/GeneratorStep.kt new file mode 100644 index 0000000..a0e52de --- /dev/null +++ b/compiler/src/main/java/com/tompee/bunch/compiler/GeneratorStep.kt @@ -0,0 +1,88 @@ +package com.tompee.bunch.compiler + +import com.google.auto.common.BasicAnnotationProcessor +import com.google.common.collect.SetMultimap +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.classinspector.elements.ElementsClassInspector +import com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview +import com.tompee.bunch.annotation.Bunch +import com.tompee.bunch.compiler.generators.AssertGenerator +import com.tompee.bunch.compiler.generators.CompanionGenerator +import com.tompee.bunch.compiler.generators.MethodGenerator +import com.tompee.bunch.compiler.properties.JavaProperties +import com.tompee.bunch.compiler.properties.KotlinProperties +import javax.annotation.processing.Filer +import javax.annotation.processing.Messager +import javax.lang.model.element.Element +import javax.lang.model.element.TypeElement +import javax.lang.model.util.Elements +import javax.lang.model.util.Types +import javax.tools.Diagnostic + +@KotlinPoetMetadataPreview +internal class GeneratorStep( + private val elements: Elements, + private val types: Types, + private val messager: Messager, + private val filer: Filer +) : BasicAnnotationProcessor.ProcessingStep { + + private val classInspector = ElementsClassInspector.create(elements, types) + + override fun process(elementsByAnnotation: SetMultimap, Element>): MutableSet { + elementsByAnnotation.entries() + .map { it.value } + .forEach { + try { + generate(it as TypeElement) + } catch (e: ProcessorException) { + messager.printMessage(Diagnostic.Kind.ERROR, e.message, e.element) + } + } + return mutableSetOf() + } + + override fun annotations(): MutableSet> { + return mutableSetOf(Bunch::class.java) + } + + private fun generate(element: TypeElement) { + val javaProperties = JavaProperties(element, elements) + val kotlinProperties = KotlinProperties(element, elements, classInspector) + + val name = javaProperties.getBunchAnnotation().name + + val fileSpec = FileSpec.builder(javaProperties.getPackageName(), name) + .addType(generateClassSpec(name, kotlinProperties, javaProperties)) + .build() + fileSpec.writeTo(filer) + } + + private fun generateClassSpec( + name: String, + kotlinProperties: KotlinProperties, + javaProperties: JavaProperties + ): TypeSpec { + val constructor = FunSpec.constructorBuilder() + .addParameter("bundle", BUNDLE) + .build() + + val methodGenerator = MethodGenerator() + return TypeSpec.classBuilder(name) + .apply { if (kotlinProperties.isInternal()) addModifiers(KModifier.INTERNAL) } + .primaryConstructor(constructor) + .addProperty( + PropertySpec.builder("bundle", BUNDLE) + .initializer("bundle") + .addModifiers(KModifier.PRIVATE) + .build() + ) + .addType(AssertGenerator().generate(javaProperties, kotlinProperties)) + .addType(CompanionGenerator().generate(javaProperties, kotlinProperties)) + .addFunctions(methodGenerator.generateAsserts(javaProperties, kotlinProperties)) + .addFunctions(methodGenerator.generateSetters(javaProperties, kotlinProperties)) + .addFunctions(methodGenerator.generateGetters(javaProperties, kotlinProperties)) + .addFunction(methodGenerator.generateCollector()) + .build() + } +} \ No newline at end of file diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/di/AppComponent.kt b/compiler/src/main/java/com/tompee/bunch/compiler/di/AppComponent.kt deleted file mode 100644 index a2d47d7..0000000 --- a/compiler/src/main/java/com/tompee/bunch/compiler/di/AppComponent.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.tompee.bunch.compiler.di - -import com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview -import com.tompee.bunch.compiler.BunchProcessor -import dagger.BindsInstance -import dagger.Component -import javax.annotation.processing.ProcessingEnvironment -import javax.inject.Singleton - -@Singleton -@Component(modules = [ProcessingModule::class, AssistedInjectModule::class]) -@KotlinPoetMetadataPreview -internal interface AppComponent { - - @Component.Factory - interface Factory { - - fun create( - @BindsInstance - environment: ProcessingEnvironment - ): AppComponent - } - - fun inject(processor: BunchProcessor) -} \ No newline at end of file diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/di/AssistedInjectModule.kt b/compiler/src/main/java/com/tompee/bunch/compiler/di/AssistedInjectModule.kt deleted file mode 100644 index 8c5eb48..0000000 --- a/compiler/src/main/java/com/tompee/bunch/compiler/di/AssistedInjectModule.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tompee.bunch.compiler.di - -import com.squareup.inject.assisted.dagger2.AssistedModule -import dagger.Module - -@AssistedModule -@Module(includes = [AssistedInject_AssistedInjectModule::class]) -internal interface AssistedInjectModule \ No newline at end of file diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/di/ProcessingModule.kt b/compiler/src/main/java/com/tompee/bunch/compiler/di/ProcessingModule.kt deleted file mode 100644 index 79da4ea..0000000 --- a/compiler/src/main/java/com/tompee/bunch/compiler/di/ProcessingModule.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.tompee.bunch.compiler.di - -import com.squareup.kotlinpoet.classinspector.elements.ElementsClassInspector -import com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview -import com.squareup.kotlinpoet.metadata.specs.ClassInspector -import dagger.Module -import dagger.Provides -import javax.annotation.processing.Messager -import javax.annotation.processing.ProcessingEnvironment -import javax.inject.Singleton -import javax.lang.model.util.Elements -import javax.lang.model.util.Types - -@Module -@KotlinPoetMetadataPreview -internal object ProcessingModule { - - @Singleton - @Provides - @JvmStatic - fun provideMessager(environment: ProcessingEnvironment): Messager { - return environment.messager - } - - @Singleton - @Provides - @JvmStatic - fun provideElements(environment: ProcessingEnvironment): Elements { - return environment.elementUtils - } - - @Singleton - @Provides - @JvmStatic - fun provideTypes(environment: ProcessingEnvironment): Types { - return environment.typeUtils - } - - @Singleton - @Provides - @JvmStatic - fun provideElementsClassInspector(environment: ProcessingEnvironment): ClassInspector { - return ElementsClassInspector.create(environment.elementUtils, environment.typeUtils) - } -} \ No newline at end of file diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/generators/AssertGenerator.kt b/compiler/src/main/java/com/tompee/bunch/compiler/generators/AssertGenerator.kt index 0beec52..99b3e3a 100644 --- a/compiler/src/main/java/com/tompee/bunch/compiler/generators/AssertGenerator.kt +++ b/compiler/src/main/java/com/tompee/bunch/compiler/generators/AssertGenerator.kt @@ -6,7 +6,6 @@ import com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview import com.tompee.bunch.compiler.ProcessorException import com.tompee.bunch.compiler.properties.JavaProperties import com.tompee.bunch.compiler.properties.KotlinProperties -import javax.inject.Inject import javax.lang.model.element.Element import javax.lang.model.element.ElementKind @@ -14,7 +13,7 @@ import javax.lang.model.element.ElementKind * Assertion class generator */ @KotlinPoetMetadataPreview -internal class AssertGenerator @Inject constructor() { +internal class AssertGenerator { /** * Generates the assert type @@ -98,7 +97,8 @@ internal class AssertGenerator @Inject constructor() { jProp.getElement().enclosedElements.filter { it.kind == ElementKind.CLASS } .flatMap { classes -> classes.enclosedElements.filter { it.kind == ElementKind.METHOD } } val jFun = - jProp.getMethods().plus(enclosedElements).firstOrNull { it.simpleName.toString() == funSpec.name } + jProp.getMethods().plus(enclosedElements) + .firstOrNull { it.simpleName.toString() == funSpec.name } ?: throw ProcessorException( jProp.getElement(), "Some functions cannot be interpreted" diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/generators/BunchGenerator.kt b/compiler/src/main/java/com/tompee/bunch/compiler/generators/BunchGenerator.kt deleted file mode 100644 index 8315335..0000000 --- a/compiler/src/main/java/com/tompee/bunch/compiler/generators/BunchGenerator.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.tompee.bunch.compiler.generators - -import com.squareup.inject.assisted.Assisted -import com.squareup.inject.assisted.AssistedInject -import com.squareup.kotlinpoet.* -import com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview -import com.tompee.bunch.compiler.BUNDLE -import com.tompee.bunch.compiler.BunchProcessor -import com.tompee.bunch.compiler.properties.JavaProperties -import com.tompee.bunch.compiler.properties.KotlinProperties -import java.io.File -import javax.annotation.processing.ProcessingEnvironment -import javax.lang.model.element.Element -import javax.lang.model.element.TypeElement - -@KotlinPoetMetadataPreview -internal class BunchGenerator @AssistedInject constructor( - private val env: ProcessingEnvironment, - private val methodGenerator: MethodGenerator, - private val companionGenerator: CompanionGenerator, - private val assertGenerator: AssertGenerator, - private val javaPropFactory: JavaProperties.Factory, - private val kotlinPropFactory: KotlinProperties.Factory, - @Assisted private val element: Element -) { - private val javaProperties by lazy { javaPropFactory.create(element as TypeElement) } - private val kotlinProperties by lazy { kotlinPropFactory.create(element as TypeElement) } - - @AssistedInject.Factory - interface Factory { - fun create(element: Element): BunchGenerator - } - - fun generate() { - val name = javaProperties.getBunchAnnotation().name - val constructor = FunSpec.constructorBuilder() - .addParameter("bundle", BUNDLE) - .build() - - val classSpec = TypeSpec.classBuilder(name) - .apply { if (kotlinProperties.isInternal()) addModifiers(KModifier.INTERNAL) } - .primaryConstructor(constructor) - .addProperty( - PropertySpec.builder("bundle", BUNDLE) - .initializer("bundle") - .addModifiers(KModifier.PRIVATE) - .build() - ) - .addType(assertGenerator.generate(javaProperties, kotlinProperties)) - .addType(companionGenerator.generate(javaProperties, kotlinProperties)) - .addFunctions(methodGenerator.generateAsserts(javaProperties, kotlinProperties)) - .addFunctions(methodGenerator.generateSetters(javaProperties, kotlinProperties)) - .addFunctions(methodGenerator.generateGetters(javaProperties, kotlinProperties)) - .addFunction(methodGenerator.generateCollector()) - .build() - - val fileSpec = FileSpec.builder(javaProperties.getPackageName(), name) - .addType(classSpec) - .build() - val kaptKotlinGeneratedDir = - env.options[BunchProcessor.KAPT_KOTLIN_GENERATED_OPTION_NAME] - fileSpec.writeTo(File(kaptKotlinGeneratedDir, "${name}_Bunch.kt")) - } -} \ No newline at end of file diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/generators/CompanionGenerator.kt b/compiler/src/main/java/com/tompee/bunch/compiler/generators/CompanionGenerator.kt index 3e32018..3feefdf 100644 --- a/compiler/src/main/java/com/tompee/bunch/compiler/generators/CompanionGenerator.kt +++ b/compiler/src/main/java/com/tompee/bunch/compiler/generators/CompanionGenerator.kt @@ -6,7 +6,6 @@ import com.tompee.bunch.compiler.* import com.tompee.bunch.compiler.extensions.wrapProof import com.tompee.bunch.compiler.properties.JavaProperties import com.tompee.bunch.compiler.properties.KotlinProperties -import javax.inject.Inject import javax.lang.model.element.Element import javax.lang.model.element.ElementKind @@ -14,7 +13,7 @@ import javax.lang.model.element.ElementKind * Generates the companion object of the Bunch. The methods include entry setter methods. */ @KotlinPoetMetadataPreview -internal class CompanionGenerator @Inject constructor() { +internal class CompanionGenerator { /** * Generates the companion method type spec @@ -73,7 +72,8 @@ internal class CompanionGenerator @Inject constructor() { jProp.getElement().enclosedElements.filter { it.kind == ElementKind.CLASS } .flatMap { classes -> classes.enclosedElements.filter { it.kind == ElementKind.METHOD } } val jFun = - jProp.getMethods().plus(enclosedElements).firstOrNull { it.simpleName.toString() == funSpec.name } + jProp.getMethods().plus(enclosedElements) + .firstOrNull { it.simpleName.toString() == funSpec.name } ?: throw ProcessorException( jProp.getElement(), "Some functions cannot be interpreted" diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/generators/MethodGenerator.kt b/compiler/src/main/java/com/tompee/bunch/compiler/generators/MethodGenerator.kt index 6cc5be1..efc7888 100644 --- a/compiler/src/main/java/com/tompee/bunch/compiler/generators/MethodGenerator.kt +++ b/compiler/src/main/java/com/tompee/bunch/compiler/generators/MethodGenerator.kt @@ -8,7 +8,6 @@ import com.tompee.bunch.compiler.* import com.tompee.bunch.compiler.extensions.wrapProof import com.tompee.bunch.compiler.properties.JavaProperties import com.tompee.bunch.compiler.properties.KotlinProperties -import javax.inject.Inject import javax.lang.model.element.Element import javax.lang.model.element.ElementKind @@ -17,7 +16,7 @@ import javax.lang.model.element.ElementKind * non-nullable getter methods, throw getter methods and the collector method */ @KotlinPoetMetadataPreview -internal class MethodGenerator @Inject constructor() { +internal class MethodGenerator { companion object { @@ -149,7 +148,8 @@ internal class MethodGenerator @Inject constructor() { jProp.getElement().enclosedElements.filter { it.kind == ElementKind.CLASS } .flatMap { classes -> classes.enclosedElements.filter { it.kind == ElementKind.METHOD } } val jFun = - jProp.getMethods().plus(enclosedElements).firstOrNull { it.simpleName.toString() == funSpec.name } + jProp.getMethods().plus(enclosedElements) + .firstOrNull { it.simpleName.toString() == funSpec.name } ?: throw ProcessorException( jProp.getElement(), "Some functions cannot be interpreted" @@ -439,7 +439,10 @@ internal class MethodGenerator @Inject constructor() { sequenceOf( FunSpec.builder(functionName) .returns(funSpec.returnType!!.copy(false)) - .addStatement("return bundle.getParcelableArrayList(\"$tag\") ?: ${sourceName}.${funSpec.name}()".wrapProof().wrapProof()) + .addStatement( + "return bundle.getParcelableArrayList(\"$tag\") ?: ${sourceName}.${funSpec.name}()".wrapProof() + .wrapProof() + ) .build() ) } diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/properties/JavaProperties.kt b/compiler/src/main/java/com/tompee/bunch/compiler/properties/JavaProperties.kt index 404e304..f2a938c 100644 --- a/compiler/src/main/java/com/tompee/bunch/compiler/properties/JavaProperties.kt +++ b/compiler/src/main/java/com/tompee/bunch/compiler/properties/JavaProperties.kt @@ -1,19 +1,17 @@ package com.tompee.bunch.compiler.properties -import com.squareup.inject.assisted.Assisted -import com.squareup.inject.assisted.AssistedInject import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.asClassName import com.tompee.bunch.annotation.Bunch -import javax.annotation.processing.ProcessingEnvironment import javax.lang.model.element.Element import javax.lang.model.element.ElementKind import javax.lang.model.element.TypeElement import javax.lang.model.type.TypeMirror +import javax.lang.model.util.Elements -internal class JavaProperties @AssistedInject constructor( - private val env: ProcessingEnvironment, - @Assisted private val typeElement: TypeElement +internal class JavaProperties( + private val typeElement: TypeElement, + private val elements: Elements ) { companion object { @@ -25,11 +23,6 @@ internal class JavaProperties @AssistedInject constructor( } } - @AssistedInject.Factory - interface Factory { - fun create(typeElement: TypeElement): JavaProperties - } - /** * Returns the underlying type element */ @@ -72,6 +65,6 @@ internal class JavaProperties @AssistedInject constructor( * Returns the package name of the type element */ fun getPackageName(): String { - return env.elementUtils.getPackageOf(typeElement).toString() + return elements.getPackageOf(typeElement).toString() } } \ No newline at end of file diff --git a/compiler/src/main/java/com/tompee/bunch/compiler/properties/KotlinProperties.kt b/compiler/src/main/java/com/tompee/bunch/compiler/properties/KotlinProperties.kt index 07d7249..781a737 100644 --- a/compiler/src/main/java/com/tompee/bunch/compiler/properties/KotlinProperties.kt +++ b/compiler/src/main/java/com/tompee/bunch/compiler/properties/KotlinProperties.kt @@ -1,7 +1,5 @@ package com.tompee.bunch.compiler.properties -import com.squareup.inject.assisted.Assisted -import com.squareup.inject.assisted.AssistedInject import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeSpec @@ -11,27 +9,19 @@ import com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview import com.squareup.kotlinpoet.metadata.specs.ClassInspector import com.squareup.kotlinpoet.metadata.specs.toTypeSpec import com.squareup.kotlinpoet.metadata.toImmutableKmClass -import javax.annotation.processing.ProcessingEnvironment import javax.lang.model.element.TypeElement +import javax.lang.model.util.Elements /** - * Contains the type element properties - * - * @property env processing environment - * @property typeElement the input type element + * Contains the Kotlin type element properties */ @KotlinPoetMetadataPreview -internal class KotlinProperties @AssistedInject constructor( - private val env: ProcessingEnvironment, - private val classInspector: ClassInspector, - @Assisted private val typeElement: TypeElement +internal class KotlinProperties( + private val typeElement: TypeElement, + private val elements: Elements, + private val classInspector: ClassInspector ) { - @AssistedInject.Factory - interface Factory { - fun create(typeElement: TypeElement): KotlinProperties - } - /** * Returns true if the annotated class is an internal class */ @@ -50,7 +40,7 @@ internal class KotlinProperties @AssistedInject constructor( * Returns the package name of the type element */ fun getPackageName(): String { - return env.elementUtils.getPackageOf(typeElement).toString() + return elements.getPackageOf(typeElement).toString() } /**