[lombok] Refactoring, cleaning, better tests
Add assertions to tests Add lombok license Provide String.[de]capitalize() implementation Get rid of weak map because it seems it is useless here
This commit is contained in:
committed by
TeamCityServer
parent
c4147bc2fd
commit
01dd3d6ed4
+2
-2
@@ -17,7 +17,7 @@ interface SyntheticJavaResolveExtension {
|
||||
) {
|
||||
fun getProvider(project: Project): SyntheticJavaPartsProvider {
|
||||
val instances = getInstances(project)
|
||||
val providers = instances.map { it.getProvider() }
|
||||
val providers = instances.map { it.buildProvider() }
|
||||
return if (providers.isEmpty()) {
|
||||
SyntheticJavaPartsProvider.EMPTY
|
||||
} else {
|
||||
@@ -26,7 +26,7 @@ interface SyntheticJavaResolveExtension {
|
||||
}
|
||||
}
|
||||
|
||||
fun getProvider(): SyntheticJavaPartsProvider
|
||||
fun buildProvider(): SyntheticJavaPartsProvider
|
||||
|
||||
}
|
||||
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2009-2021 The Project Lombok Authors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+1
-1
@@ -13,5 +13,5 @@ class LombokResolveExtension(pluginConfig: LombokPluginConfig) : SyntheticJavaRe
|
||||
|
||||
private val config = pluginConfig.configFile?.let(LombokConfig::parse) ?: LombokConfig.Empty
|
||||
|
||||
override fun getProvider(): SyntheticJavaPartsProvider = LombokSyntheticJavaPartsProvider(config)
|
||||
override fun buildProvider(): SyntheticJavaPartsProvider = LombokSyntheticJavaPartsProvider(config)
|
||||
}
|
||||
|
||||
+8
-16
@@ -37,7 +37,7 @@ class LombokSyntheticJavaPartsProvider(config: LombokConfig) : SyntheticJavaPart
|
||||
* but for us it is much easier to run full generation for class once
|
||||
* hence we cache results and reuse it
|
||||
*/
|
||||
private val partsCache: MutableMap<ClassDescriptor, SyntheticParts> = WeakHashMap()
|
||||
private val partsCache: MutableMap<ClassDescriptor, SyntheticParts> = HashMap()
|
||||
|
||||
override fun getMethodNames(thisDescriptor: ClassDescriptor): List<Name> =
|
||||
getSyntheticParts(thisDescriptor).methods.map { it.name }
|
||||
@@ -75,28 +75,19 @@ class LombokSyntheticJavaPartsProvider(config: LombokConfig) : SyntheticJavaPart
|
||||
}
|
||||
} ?: SyntheticParts.Empty
|
||||
|
||||
private fun computeSyntheticParts(descriptor: ClassDescriptor): SyntheticParts =
|
||||
processors.map { it.contribute(descriptor) }.reduce { a, b -> a + b }
|
||||
private fun computeSyntheticParts(descriptor: ClassDescriptor): SyntheticParts {
|
||||
val builder = SyntheticPartsBuilder()
|
||||
processors.forEach { it.contribute(descriptor, builder) }
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Deduplicates generated functions using name and argument counts, as lombok does
|
||||
*/
|
||||
private fun <T : FunctionDescriptor> addNonExistent(result: MutableCollection<T>, toAdd: List<T>) {
|
||||
if (toAdd.isEmpty()) return
|
||||
|
||||
val index = mutableMapOf<Name, List<T>>()
|
||||
|
||||
fun addToIndex(f: T) {
|
||||
index.merge(f.name, listOf(f)) { a, b -> a + b}
|
||||
}
|
||||
|
||||
result.forEach(::addToIndex)
|
||||
|
||||
toAdd.forEach { f ->
|
||||
val existing = index.getOrDefault(f.name, emptyList())
|
||||
if (existing.none { sameSignature (it, f) } ) {
|
||||
if (result.none { sameSignature(it, f) }) {
|
||||
result += f
|
||||
addToIndex(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +97,7 @@ class LombokSyntheticJavaPartsProvider(config: LombokConfig) : SyntheticJavaPart
|
||||
|
||||
/**
|
||||
* Lombok treat functions as having the same signature by arguments count only
|
||||
* Corresponding code in lombok - https://github.com/projectlombok/lombok/blob/v1.18.20/src/core/lombok/javac/handlers/JavacHandlerUtil.java#L752
|
||||
*/
|
||||
private fun sameSignature(a: FunctionDescriptor, b: FunctionDescriptor): Boolean {
|
||||
val aVararg = a.valueParameters.any { it.varargElementType != null }
|
||||
|
||||
+139
-151
@@ -20,9 +20,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
*
|
||||
*/
|
||||
|
||||
abstract class AnnotationCompanion<T> {
|
||||
|
||||
abstract val name: FqName
|
||||
abstract class AnnotationCompanion<T>(val name: FqName) {
|
||||
|
||||
abstract fun extract(annotation: AnnotationDescriptor): T
|
||||
|
||||
@@ -30,10 +28,7 @@ abstract class AnnotationCompanion<T> {
|
||||
annotated.annotations.findAnnotation(name)?.let(this::extract)
|
||||
}
|
||||
|
||||
abstract class AnnotationAndConfigCompanion<T> {
|
||||
|
||||
abstract val annotationName: FqName
|
||||
|
||||
abstract class AnnotationAndConfigCompanion<T>(private val annotationName: FqName) {
|
||||
|
||||
abstract fun extract(annotation: AnnotationDescriptor?, config: LombokConfig): T
|
||||
|
||||
@@ -53,155 +48,148 @@ abstract class AnnotationAndConfigCompanion<T> {
|
||||
|
||||
}
|
||||
|
||||
data class Accessors(
|
||||
val fluent: Boolean = false,
|
||||
val chain: Boolean = false,
|
||||
val noIsPrefix: Boolean = false,
|
||||
val prefix: List<String> = emptyList()
|
||||
) {
|
||||
companion object : AnnotationAndConfigCompanion<Accessors>() {
|
||||
object LombokAnnotations {
|
||||
class Accessors(
|
||||
val fluent: Boolean = false,
|
||||
val chain: Boolean = false,
|
||||
val noIsPrefix: Boolean = false,
|
||||
val prefix: List<String> = emptyList()
|
||||
) {
|
||||
companion object : AnnotationAndConfigCompanion<Accessors>(LombokNames.ACCESSORS) {
|
||||
|
||||
override val annotationName: FqName = LombokNames.ACCESSORS
|
||||
override fun extract(annotation: AnnotationDescriptor?, config: LombokConfig): Accessors {
|
||||
val fluent =
|
||||
annotation?.getBooleanArgument("fluent")
|
||||
?: config.getBoolean("lombok.accessors.fluent")
|
||||
?: false
|
||||
val chain =
|
||||
annotation?.getBooleanArgument("chain")
|
||||
?: config.getBoolean("lombok.accessors.chain")
|
||||
?: fluent
|
||||
val noIsPrefix = config.getBoolean("lombok.getter.noIsPrefix") ?: false
|
||||
val prefix =
|
||||
annotation?.getStringArrayArgument("prefix")
|
||||
?: config.getMultiString("lombok.accessors.prefix")
|
||||
?: emptyList()
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor?, config: LombokConfig): Accessors {
|
||||
val fluent =
|
||||
annotation?.getBooleanArgument("fluent")
|
||||
?: config.getBoolean("lombok.accessors.fluent")
|
||||
?: false
|
||||
val chain =
|
||||
annotation?.getBooleanArgument("chain")
|
||||
?: config.getBoolean("lombok.accessors.chain")
|
||||
?: fluent
|
||||
val noIsPrefix = config.getBoolean("lombok.getter.noIsPrefix") ?: false
|
||||
val prefix =
|
||||
annotation?.getStringArrayArgument("prefix")
|
||||
?: config.getMultiString("lombok.accessors.prefix")
|
||||
?: emptyList()
|
||||
return Accessors(fluent, chain, noIsPrefix, prefix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Getter(val visibility: AccessLevel = AccessLevel.PUBLIC) {
|
||||
companion object : AnnotationCompanion<Getter>(LombokNames.GETTER) {
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): Getter =
|
||||
Getter(
|
||||
visibility = getAccessLevel(annotation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class Setter(val visibility: AccessLevel = AccessLevel.PUBLIC) {
|
||||
companion object : AnnotationCompanion<Setter>( LombokNames.SETTER) {
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): Setter =
|
||||
Setter(
|
||||
visibility = getAccessLevel(annotation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class With(val visibility: AccessLevel = AccessLevel.PUBLIC) {
|
||||
companion object : AnnotationCompanion<With>(LombokNames.WITH) {
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): With =
|
||||
With(
|
||||
visibility = getAccessLevel(annotation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
interface ConstructorAnnotation {
|
||||
val visibility: DescriptorVisibility
|
||||
val staticName: String?
|
||||
}
|
||||
|
||||
class NoArgsConstructor(
|
||||
override val visibility: DescriptorVisibility,
|
||||
override val staticName: String?
|
||||
) : ConstructorAnnotation {
|
||||
companion object : AnnotationCompanion<NoArgsConstructor>( LombokNames.NO_ARGS_CONSTRUCTOR) {
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): NoArgsConstructor =
|
||||
NoArgsConstructor(
|
||||
visibility = getVisibility(annotation, "access"),
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class AllArgsConstructor(
|
||||
override val visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC,
|
||||
override val staticName: String? = null
|
||||
) : ConstructorAnnotation {
|
||||
companion object : AnnotationCompanion<AllArgsConstructor>(LombokNames.ALL_ARGS_CONSTRUCTOR) {
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): AllArgsConstructor =
|
||||
AllArgsConstructor(
|
||||
visibility = getVisibility(annotation, "access"),
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class RequiredArgsConstructor(
|
||||
override val visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC,
|
||||
override val staticName: String? = null
|
||||
) : ConstructorAnnotation {
|
||||
companion object : AnnotationCompanion<RequiredArgsConstructor>(LombokNames.REQUIRED_ARGS_CONSTRUCTOR) {
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): RequiredArgsConstructor =
|
||||
RequiredArgsConstructor(
|
||||
visibility = getVisibility(annotation, "access"),
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class Data(val staticConstructor: String?) {
|
||||
|
||||
fun asSetter(): Setter = Setter()
|
||||
|
||||
fun asGetter(): Getter = Getter()
|
||||
|
||||
fun asRequiredArgsConstructor(): RequiredArgsConstructor = RequiredArgsConstructor(
|
||||
staticName = staticConstructor
|
||||
)
|
||||
|
||||
companion object : AnnotationCompanion<Data>(LombokNames.DATA) {
|
||||
override fun extract(annotation: AnnotationDescriptor): Data =
|
||||
Data(
|
||||
staticConstructor = annotation.getNonBlankStringArgument("staticConstructor")
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Value(val staticConstructor: String?) {
|
||||
|
||||
fun asGetter(): Getter = Getter()
|
||||
|
||||
fun asAllArgsConstructor(): AllArgsConstructor = AllArgsConstructor(
|
||||
staticName = staticConstructor
|
||||
)
|
||||
|
||||
companion object : AnnotationCompanion<Value>(LombokNames.VALUE) {
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): Value =
|
||||
Value(
|
||||
staticConstructor = annotation.getNonBlankStringArgument("staticConstructor")
|
||||
)
|
||||
|
||||
return Accessors(fluent, chain, noIsPrefix, prefix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Getter(val visibility: AccessLevel = AccessLevel.PUBLIC) {
|
||||
companion object : AnnotationCompanion<Getter>() {
|
||||
override val name: FqName = LombokNames.GETTER
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): Getter =
|
||||
Getter(
|
||||
visibility = getAccessLevel(annotation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Setter(val visibility: AccessLevel = AccessLevel.PUBLIC) {
|
||||
companion object : AnnotationCompanion<Setter>() {
|
||||
override val name: FqName = LombokNames.SETTER
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): Setter =
|
||||
Setter(
|
||||
visibility = getAccessLevel(annotation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class With(val visibility: AccessLevel = AccessLevel.PUBLIC) {
|
||||
companion object : AnnotationCompanion<With>() {
|
||||
override val name: FqName = LombokNames.WITH
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): With =
|
||||
With(
|
||||
visibility = getAccessLevel(annotation)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
interface ConstructorAnnotation {
|
||||
val visibility: DescriptorVisibility
|
||||
val staticName: String?
|
||||
}
|
||||
|
||||
data class NoArgsConstructor(
|
||||
override val visibility: DescriptorVisibility,
|
||||
override val staticName: String?
|
||||
) : ConstructorAnnotation {
|
||||
companion object : AnnotationCompanion<NoArgsConstructor>() {
|
||||
override val name: FqName = LombokNames.NO_ARGS_CONSTRUCTOR
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): NoArgsConstructor =
|
||||
NoArgsConstructor(
|
||||
visibility = getVisibility(annotation, "access"),
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class AllArgsConstructor(
|
||||
override val visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC,
|
||||
override val staticName: String? = null
|
||||
) : ConstructorAnnotation {
|
||||
companion object : AnnotationCompanion<AllArgsConstructor>() {
|
||||
override val name: FqName = LombokNames.ALL_ARGS_CONSTRUCTOR
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): AllArgsConstructor =
|
||||
AllArgsConstructor(
|
||||
visibility = getVisibility(annotation, "access"),
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class RequiredArgsConstructor(
|
||||
override val visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC,
|
||||
override val staticName: String? = null
|
||||
) : ConstructorAnnotation {
|
||||
companion object : AnnotationCompanion<RequiredArgsConstructor>() {
|
||||
override val name: FqName = LombokNames.REQUIRED_ARGS_CONSTRUCTOR
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): RequiredArgsConstructor =
|
||||
RequiredArgsConstructor(
|
||||
visibility = getVisibility(annotation, "access"),
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Data(val staticConstructor: String?) {
|
||||
|
||||
fun asSetter(): Setter = Setter()
|
||||
|
||||
fun asGetter(): Getter = Getter()
|
||||
|
||||
fun asRequiredArgsConstructor(): RequiredArgsConstructor = RequiredArgsConstructor(
|
||||
staticName = staticConstructor
|
||||
)
|
||||
|
||||
companion object : AnnotationCompanion<Data>() {
|
||||
override val name: FqName = LombokNames.DATA
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): Data =
|
||||
Data(
|
||||
staticConstructor = annotation.getNonBlankStringArgument("staticConstructor")
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
data class Value(val staticConstructor: String?) {
|
||||
|
||||
fun asGetter(): Getter = Getter()
|
||||
|
||||
fun asAllArgsConstructor(): AllArgsConstructor = AllArgsConstructor(
|
||||
staticName = staticConstructor
|
||||
)
|
||||
|
||||
companion object : AnnotationCompanion<Value>() {
|
||||
override val name: FqName = LombokNames.VALUE
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): Value =
|
||||
Value(
|
||||
staticConstructor = annotation.getNonBlankStringArgument("staticConstructor")
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+8
-9
@@ -7,26 +7,26 @@ package org.jetbrains.kotlin.lombok.processor
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.ConstructorAnnotation
|
||||
import org.jetbrains.kotlin.lombok.utils.ValueParameter
|
||||
import org.jetbrains.kotlin.lombok.utils.createJavaConstructor
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.ConstructorAnnotation
|
||||
import org.jetbrains.kotlin.lombok.utils.LombokValueParameter
|
||||
import org.jetbrains.kotlin.lombok.utils.createFunction
|
||||
import org.jetbrains.kotlin.lombok.utils.createJavaConstructor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
abstract class AbstractConstructorProcessor<A : ConstructorAnnotation> : Processor {
|
||||
|
||||
override fun contribute(classDescriptor: ClassDescriptor): SyntheticParts {
|
||||
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
|
||||
val valueParameters = getPropertiesForParameters(classDescriptor).map { property ->
|
||||
ValueParameter(property.name, property.type)
|
||||
LombokValueParameter(property.name, property.type)
|
||||
}
|
||||
|
||||
val result = getAnnotation(classDescriptor)?.let { annotation ->
|
||||
getAnnotation(classDescriptor)?.let { annotation ->
|
||||
if (annotation.staticName == null) {
|
||||
val constructor = classDescriptor.createJavaConstructor(
|
||||
valueParameters = valueParameters,
|
||||
visibility = annotation.visibility
|
||||
)
|
||||
SyntheticParts(constructors = listOfNotNull(constructor))
|
||||
partsBuilder.addConstructor(constructor)
|
||||
} else {
|
||||
val function = classDescriptor.createFunction(
|
||||
Name.identifier(annotation.staticName!!),
|
||||
@@ -36,10 +36,9 @@ abstract class AbstractConstructorProcessor<A : ConstructorAnnotation> : Process
|
||||
visibility = annotation.visibility,
|
||||
receiver = null
|
||||
)
|
||||
SyntheticParts(staticFunctions = listOf(function))
|
||||
partsBuilder.addStaticFunction(function)
|
||||
}
|
||||
}
|
||||
return result ?: SyntheticParts.Empty
|
||||
}
|
||||
|
||||
protected abstract fun getAnnotation(classDescriptor: ClassDescriptor): A?
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.lombok.processor
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.AllArgsConstructor
|
||||
import org.jetbrains.kotlin.lombok.config.Value
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.AllArgsConstructor
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Value
|
||||
import org.jetbrains.kotlin.lombok.utils.getJavaFields
|
||||
|
||||
class AllArgsConstructorProcessor : AbstractConstructorProcessor<AllArgsConstructor>() {
|
||||
|
||||
+7
-4
@@ -9,24 +9,27 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.*
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Accessors
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Getter
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Data
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Value
|
||||
import org.jetbrains.kotlin.lombok.utils.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class GetterProcessor(private val config: LombokConfig) : Processor {
|
||||
|
||||
override fun contribute(classDescriptor: ClassDescriptor): SyntheticParts {
|
||||
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
|
||||
val globalAccessors = Accessors.get(classDescriptor, config)
|
||||
val clGetter =
|
||||
Getter.getOrNull(classDescriptor)
|
||||
?: Data.getOrNull(classDescriptor)?.asGetter()
|
||||
?: Value.getOrNull(classDescriptor)?.asGetter()
|
||||
|
||||
val functions = classDescriptor
|
||||
classDescriptor
|
||||
.getJavaFields()
|
||||
.collectWithNotNull { Getter.getOrNull(it) ?: clGetter }
|
||||
.mapNotNull { (field, annotation) -> createGetter(classDescriptor, field, annotation, globalAccessors) }
|
||||
|
||||
return SyntheticParts(functions)
|
||||
.forEach(partsBuilder::addMethod)
|
||||
}
|
||||
|
||||
private fun createGetter(
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.lombok.processor
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.NoArgsConstructor
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.NoArgsConstructor
|
||||
|
||||
class NoArgsConstructorProcessor : AbstractConstructorProcessor<NoArgsConstructor>() {
|
||||
|
||||
|
||||
+2
-1
@@ -12,5 +12,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
*/
|
||||
interface Processor {
|
||||
|
||||
fun contribute(classDescriptor: ClassDescriptor): SyntheticParts
|
||||
fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder)
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ import com.intellij.psi.PsiField
|
||||
import com.intellij.psi.PsiModifier
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.Data
|
||||
import org.jetbrains.kotlin.lombok.config.RequiredArgsConstructor
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Data
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.RequiredArgsConstructor
|
||||
import org.jetbrains.kotlin.lombok.utils.LombokNames
|
||||
import org.jetbrains.kotlin.lombok.utils.getJavaFields
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
|
||||
+8
-5
@@ -9,22 +9,25 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.lombok.config.*
|
||||
import org.jetbrains.kotlin.lombok.utils.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Accessors
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Setter
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Data
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
|
||||
class SetterProcessor(private val config: LombokConfig) : Processor {
|
||||
|
||||
override fun contribute(classDescriptor: ClassDescriptor): SyntheticParts {
|
||||
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
|
||||
//lombok doesn't generate setters for enums
|
||||
if (classDescriptor.kind == ClassKind.ENUM_CLASS) return SyntheticParts.Empty
|
||||
if (classDescriptor.kind == ClassKind.ENUM_CLASS) return
|
||||
|
||||
val globalAccessors = Accessors.get(classDescriptor, config)
|
||||
val clSetter = Setter.getOrNull(classDescriptor) ?: Data.getOrNull(classDescriptor)?.asSetter()
|
||||
|
||||
val functions = classDescriptor
|
||||
classDescriptor
|
||||
.getJavaFields()
|
||||
.collectWithNotNull { field -> Setter.getOrNull(field) ?: clSetter.takeIf { field.isVar } }
|
||||
.mapNotNull { (field, setter) -> createSetter(classDescriptor, field, setter, globalAccessors) }
|
||||
return SyntheticParts(functions)
|
||||
.forEach(partsBuilder::addMethod)
|
||||
}
|
||||
|
||||
private fun createSetter(
|
||||
@@ -45,7 +48,7 @@ class SetterProcessor(private val config: LombokConfig) : Processor {
|
||||
|
||||
classDescriptor.createFunction(
|
||||
Name.identifier(functionName),
|
||||
listOf(ValueParameter(field.name, field.type)),
|
||||
listOf(LombokValueParameter(field.name, field.type)),
|
||||
returnType,
|
||||
visibility = getter.visibility.toDescriptorVisibility()
|
||||
)
|
||||
|
||||
+21
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.lombok.processor
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
|
||||
data class SyntheticParts(
|
||||
class SyntheticParts(
|
||||
val methods: List<SimpleFunctionDescriptor> = emptyList(),
|
||||
val staticFunctions: List<SimpleFunctionDescriptor> = emptyList(),
|
||||
val constructors: List<ClassConstructorDescriptor> = emptyList()
|
||||
@@ -24,3 +24,23 @@ data class SyntheticParts(
|
||||
val Empty = SyntheticParts()
|
||||
}
|
||||
}
|
||||
|
||||
class SyntheticPartsBuilder {
|
||||
private val methods = mutableListOf<SimpleFunctionDescriptor>()
|
||||
private val staticFunctions = mutableListOf<SimpleFunctionDescriptor>()
|
||||
private val constructors = mutableListOf<ClassConstructorDescriptor>()
|
||||
|
||||
fun addMethod(method: SimpleFunctionDescriptor) {
|
||||
methods += method
|
||||
}
|
||||
|
||||
fun addStaticFunction(function: SimpleFunctionDescriptor) {
|
||||
staticFunctions += function
|
||||
}
|
||||
|
||||
fun addConstructor(constructor: ClassConstructorDescriptor) {
|
||||
constructors += constructor
|
||||
}
|
||||
|
||||
fun build(): SyntheticParts = SyntheticParts(methods, staticFunctions, constructors)
|
||||
}
|
||||
|
||||
+5
-7
@@ -9,21 +9,19 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.AccessLevel
|
||||
import org.jetbrains.kotlin.lombok.config.With
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.With
|
||||
import org.jetbrains.kotlin.lombok.utils.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class WithProcessor : Processor {
|
||||
override fun contribute(classDescriptor: ClassDescriptor): SyntheticParts {
|
||||
|
||||
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
|
||||
val clWith = With.getOrNull(classDescriptor)
|
||||
|
||||
val functions = classDescriptor
|
||||
classDescriptor
|
||||
.getJavaFields()
|
||||
.collectWithNotNull { With.getOrNull(it) ?: clWith }
|
||||
.mapNotNull { (field, annotation) -> createWith(classDescriptor, field, annotation) }
|
||||
|
||||
return SyntheticParts(functions)
|
||||
.forEach(partsBuilder::addMethod)
|
||||
}
|
||||
|
||||
private fun createWith(
|
||||
@@ -37,7 +35,7 @@ class WithProcessor : Processor {
|
||||
|
||||
return classDescriptor.createFunction(
|
||||
Name.identifier(functionName),
|
||||
listOf(ValueParameter(field.name, field.type)),
|
||||
listOf(LombokValueParameter(field.name, field.type)),
|
||||
classDescriptor.defaultType,
|
||||
visibility = with.visibility.toDescriptorVisibility()
|
||||
)
|
||||
|
||||
+4
-5
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.lombok.utils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -18,11 +17,11 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
||||
|
||||
data class ValueParameter(val name: Name, val type: KotlinType)
|
||||
data class LombokValueParameter(val name: Name, val type: KotlinType)
|
||||
|
||||
fun ClassDescriptor.createFunction(
|
||||
name: Name,
|
||||
valueParameters: List<ValueParameter>,
|
||||
valueParameters: List<LombokValueParameter>,
|
||||
returnType: KotlinType?,
|
||||
typeParameters: List<TypeParameterDescriptor> = emptyList(),
|
||||
modality: Modality? = Modality.OPEN,
|
||||
@@ -52,7 +51,7 @@ fun ClassDescriptor.createFunction(
|
||||
}
|
||||
|
||||
fun ClassDescriptor.createJavaConstructor(
|
||||
valueParameters: List<ValueParameter>,
|
||||
valueParameters: List<LombokValueParameter>,
|
||||
visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC
|
||||
): ClassConstructorDescriptor {
|
||||
val constructor = JavaClassConstructorDescriptor.create(
|
||||
@@ -74,7 +73,7 @@ fun ClassDescriptor.createJavaConstructor(
|
||||
return constructor
|
||||
}
|
||||
|
||||
private fun CallableDescriptor.makeValueParameter(param: ValueParameter, index: Int): ValueParameterDescriptor {
|
||||
private fun CallableDescriptor.makeValueParameter(param: LombokValueParameter, index: Int): ValueParameterDescriptor {
|
||||
return ValueParameterDescriptorImpl(
|
||||
containingDeclaration = this,
|
||||
original = null,
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.lombok.utils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.Accessors
|
||||
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Accessors
|
||||
|
||||
object AccessorNames {
|
||||
const val IS = "is"
|
||||
|
||||
@@ -5,8 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.lombok.utils
|
||||
|
||||
import java.util.*
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <E, R> Collection<E>.collectWithNotNull(f: (E) -> R?): List<Pair<E, R>> =
|
||||
map { it to f(it) }.filter { it.second != null } as List<Pair<E, R>>
|
||||
|
||||
fun String?.trimToNull(): String? = this?.trim()?.takeIf { it.isNotEmpty() }
|
||||
|
||||
//because capitalize from stdlib is deprecated
|
||||
fun String.capitalize(): String = replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
||||
|
||||
fun String.decapitalize(): String = replaceFirstChar { if (it.isUpperCase()) it.lowercase(Locale.getDefault()) else it.toString() }
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fun <T> assertEquals(a: T, b: T) {
|
||||
if (a != b) throw RuntimeException("'$a' was not equal to '$b'")
|
||||
}
|
||||
@@ -31,11 +31,13 @@ class Test {
|
||||
fun run() {
|
||||
val obj = DataExample("name")
|
||||
obj.getName()
|
||||
val name = obj.name
|
||||
assertEquals(obj.name, "name")
|
||||
obj.getTags()
|
||||
val tags = obj.tags
|
||||
obj.setScore(1.5)
|
||||
assertEquals(obj.score, 1.5)
|
||||
obj.score = 2.5
|
||||
assertEquals(obj.score, 2.5)
|
||||
|
||||
val ex: DataExample.Exercise<Int> = DataExample.Exercise.of("name", 12)
|
||||
}
|
||||
|
||||
+3
-1
@@ -24,6 +24,8 @@ public class ConstructorExample<A, B> {
|
||||
class Test {
|
||||
fun run() {
|
||||
val generated: ConstructorExample<Long, Boolean> = ConstructorExample.of(12, 42L, true)
|
||||
val generatedReq: ConstructorExample<String, Boolean> = ConstructorExample.of("234");
|
||||
assertEquals(generated.name, 42L)
|
||||
val generatedReq: ConstructorExample<String, Boolean> = ConstructorExample.of("234")
|
||||
assertEquals(generatedReq.name, "234")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FluentTest {
|
||||
class Test {
|
||||
fun run() {
|
||||
val obj = FluentTest()
|
||||
val getter = obj.age()
|
||||
assertEquals(obj.age(), 10)
|
||||
|
||||
obj.primitiveBoolean()
|
||||
|
||||
|
||||
+1
@@ -36,5 +36,6 @@ public class ConstructorExample {
|
||||
class Test {
|
||||
fun run() {
|
||||
val generated = ConstructorExample("foo", true)
|
||||
assertEquals(generated.foo, "foo")
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -38,5 +38,6 @@ public class ConstructorExample {
|
||||
class Test {
|
||||
fun run() {
|
||||
val generated = ConstructorExample.build("foo", true, 12)
|
||||
assertEquals(generated.foo, "foo")
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -27,7 +27,9 @@ class Test {
|
||||
fun run() {
|
||||
val obj = SetterTest()
|
||||
obj.setAge(42)
|
||||
obj.age = 42
|
||||
assertEquals(obj.age, 42)
|
||||
obj.age = 43
|
||||
assertEquals(obj.age, 43)
|
||||
|
||||
obj.setPrimitiveBoolean(true)
|
||||
|
||||
|
||||
@@ -29,8 +29,11 @@ class Test {
|
||||
fun run() {
|
||||
val obj = SetterTest()
|
||||
obj.fluent(12)
|
||||
assertEquals(obj.fluent(), 12)
|
||||
obj.setChained("zz").getChained()
|
||||
assertEquals(obj.getChained(), "zz")
|
||||
obj.whyNotBoth("zzz").whyNotBoth()
|
||||
assertEquals(obj.whyNotBoth(), "zzz")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,12 +31,14 @@ import lombok.*;
|
||||
class Test {
|
||||
fun run() {
|
||||
val obj = ValueExample("name", 12, 4.5)
|
||||
obj.getName()
|
||||
val name = obj.name
|
||||
obj.getAge()
|
||||
val age = obj.age
|
||||
val score = obj.score
|
||||
assertEquals(obj.getName(), "name")
|
||||
assertEquals(obj.name, "name")
|
||||
assertEquals(obj.getAge(), 12)
|
||||
assertEquals(obj.age, 12)
|
||||
assertEquals(obj.score, 4.5)
|
||||
|
||||
val ex: ValueExample.Exercise<Int> = ValueExample.Exercise.of("name", 12)
|
||||
val ex: ValueExample.Exercise<Int> = ValueExample.Exercise.of("nam1e", 42)
|
||||
assertEquals(ex.name, "nam1e")
|
||||
assertEquals(ex.value, 42)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-15
@@ -1,25 +1,17 @@
|
||||
//FILE: WithExample.java
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.With;
|
||||
import lombok.*;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WithExample {
|
||||
|
||||
//todo replace constructors with annotations when supported
|
||||
public WithExample() {
|
||||
@Getter @With private int age = 10;
|
||||
|
||||
}
|
||||
@Getter @With private String name;
|
||||
|
||||
public WithExample(int age, String name) {
|
||||
|
||||
}
|
||||
|
||||
@With private int age = 10;
|
||||
|
||||
@With private String name;
|
||||
|
||||
static void test() {
|
||||
WithExample obj = new WithExample().withAge(16).withName("fooo");
|
||||
public static WithExample test() {
|
||||
return new WithExample().withAge(16).withName("fooo");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +19,10 @@ public class WithExample {
|
||||
//FILE: test.kt
|
||||
|
||||
class Test {
|
||||
|
||||
fun run() {
|
||||
val obj: WithExample = WithExample().withAge(16).withName("fooo")
|
||||
assertEquals(obj.getName(), "fooo")
|
||||
assertEquals(obj.age, 16)
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -18,9 +18,13 @@ import java.net.URLClassLoader
|
||||
abstract class AbstractLombokCompileTest : CodegenTestCase() {
|
||||
|
||||
private val commonClassLoader = URLClassLoader(arrayOf(getLombokJar().toURI().toURL()))
|
||||
private val commonSourceFile = TestFile(
|
||||
"common.kt",
|
||||
File("plugins/lombok/lombok-compiler-plugin/testData/common.kt").readText()
|
||||
)
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||
compile(files, true, true)
|
||||
compile(files + commonSourceFile, true, true)
|
||||
}
|
||||
|
||||
override fun setupEnvironment(environment: KotlinCoreEnvironment) {
|
||||
|
||||
Reference in New Issue
Block a user