Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.

Commit bd563ea

Browse files
committed
refactor
1 parent b239f3b commit bd563ea

File tree

8 files changed

+63
-55
lines changed

8 files changed

+63
-55
lines changed

README.md

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,50 +69,33 @@ autoCompilerPlugins := true
6969
addCompilerPlugin("org.bitlap" %% "validation-scala-plugin" % "latest version")
7070
```
7171

72-
### `@Validated`
73-
74-
Add `@Validated` to method:
75-
```scala
76-
import bitlap.validation.extension.Validated
72+
### Cascade Validation
7773

78-
@Validated def update(person1: Person, person2: Person)
79-
```
8074
Then, checking code will be automatically inserted during compilation and may throw an `IllegalArgumentException` if the constraint checking fails.
8175

82-
If you do not wish to throw an exception directly, you should add a `bind: BindingResult` parameter to method:.
83-
```scala
84-
import bitlap.validation.extension.Validated
85-
86-
@Validated def update(person1: Person, person2: Person, bind: BindingResult = BindingResult.default)
87-
```
88-
89-
The plugin captures the `bind` parameters based on the type, so the name doesn't matter.
90-
91-
### Cascade Validation
92-
76+
If you do not wish to throw an exception directly, you should add a `bind: BindingResult` parameter to method:
9377
```scala
9478
import jakarta.validation.Valid
95-
import bitlap.validation.extension.Validated
9679
import jakarta.validation.constraints.NotNull
9780

98-
@Validated def validatedTwoParams(@Valid person1: Person, @Valid person2: Person): String
81+
def validatedTwoParams(@Valid person1: Person, @Valid person2: Person): String
9982

100-
@Validated def validatedOneParams(@Valid person1: Person): String
83+
def validatedOneParams(@Valid person1: Person): String
10184

102-
@Validated def validatedBindParams(@Valid person1: Person, bindingError: BindingResult = BindingResult.default): String
85+
// The plugin captures the `bind` parameters based on the type, so the name doesn't matter.
86+
def validatedBindParams(@Valid person1: Person, bindingError: BindingResult = BindingResult.default): String
10387

104-
@Validated def validatedNotNullParams(@Valid @NotNull person1: Person): String
88+
def validatedNotNullParams(@Valid @NotNull person1: Person): String
10589
```
10690

10791
### Non-Cascade Validation
10892

10993
```scala
110-
import bitlap.validation.extension.Validated
11194
import jakarta.validation.constraints.{ NotBlank, NotNull }
11295

113-
@Validated def validatedNotNullParams(@NotNull person1: Person): String
96+
def validatedNotNullParams(@NotNull person1: Person): String
11497

115-
@Validated def validatedNotEmptyParam(@NotBlank name: String): String
98+
def validatedNotEmptyParam(@NotBlank name: String): String
11699
```
117100

118101
### Limitation

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ val jodaConvertVersion = "2.2.3"
1515
val jodaTimeVersion = "2.12.5"
1616
val specs2Version = "4.20.3"
1717
val zioVersion = "2.0.19"
18-
val `example-dependency-version` = "0.0.0+106-e5acc4be-SNAPSHOT"
18+
val `example-dependency-version` = "0.0.0+100-22e7d34d+20231118-1835-SNAPSHOT"
1919
val supportCrossVersionList = Seq(scala3_Version, scala2_13Version)
2020

2121
inThisBuild(

docs/support-annotations.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Validation of annotation constraints on generic parameters is not supported beca
2727
- NegativeOrZer
2828
- Positive
2929
- PositiveOrZero
30+
- NotNull
3031

3132
## `jakarta.validation`
3233

examples/src/main/scala/bitlap/validation/examples/PersonNormalService.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,20 @@ import jakarta.validation.constraints.{ NotBlank, NotNull }
77
final class PersonNormalService {
88

99
// cascade
10-
@Validated
1110
def validatedTwoParams(@Valid person1: Person, @Valid person2: Person): String =
1211
s"${person1.name} - $person2"
1312

1413
// cascade
15-
@Validated
1614
def validatedOneParam(@Valid person1: Person): String =
1715
s"${person1.name}"
1816

1917
// cascade
20-
@Validated
2118
def validatedBindParams(@Valid person1: Person, bindingError: BindingResult = BindingResult.default): String =
2219
s"${person1.name} - violationsCount: ${bindingError.violations.map(_.getMessage)}"
2320

24-
@Validated
2521
def validatedNotNullParam(@NotNull person1: Person): String =
2622
s"${person1.name}"
2723

28-
@Validated
2924
def validatedNotEmptyParam(@NotBlank name: String): String =
3025
s"$name"
3126
}

examples/src/main/scala/bitlap/validation/examples/PersonZioService.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,26 @@ import zio.*
88
final class PersonZioService {
99

1010
// cascade
11-
@Validated
1211
def zioValidatedTwoParams(
1312
@Valid person1: Person,
1413
@Valid person2: Person
1514
): ZIO[Any, Nothing, String] =
1615
ZIO.succeed(s"${person1.name} - $person2")
1716

1817
// cascade
19-
@Validated
2018
def zioValidatedOneParam(@Valid person1: Person): ZIO[Any, Nothing, String] =
2119
ZIO.succeed(s"${person1.name}")
2220

2321
// cascade
24-
@Validated
2522
def zioValidatedBindParam(
2623
@Valid person1: Person,
2724
bindingError: BindingResult = BindingResult.default
2825
): ZIO[Any, Nothing, String] =
2926
ZIO.succeed(s"${person1.name} - violationsCount: ${bindingError.violations.map(_.getMessage)}")
3027

31-
@Validated
3228
def zioValidatedNotNullParam(@NotNull person1: Person): ZIO[Any, Nothing, String] =
3329
ZIO.succeed(s"${person1.name}")
3430

35-
@Validated
3631
def zioValidatedNotEmptyParam(@NotBlank name: String): ZIO[Any, Nothing, String] =
3732
ZIO.succeed(s"$name")
3833

validation-scala-core/src/main/scala/bitlap/validation/extension/Validated.scala

Lines changed: 0 additions & 6 deletions
This file was deleted.

validation-scala-plugin/src/main/scala/bitlap/validation/plugin/TermsName.scala

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package bitlap.validation.plugin
33
private[plugin] object TermsName {
44

55
final val BindingResult_Class = "bitlap.validation.extension.BindingResult"
6-
final val Validated_Annotation = "bitlap.validation.extension.Validated"
76
final val Preconditions_Class = "bitlap.validation.extension.Preconditions"
87
final val ZioPreconditions_Class = "bitlap.validation.ext.ZioPreconditions"
98
final val Zio_Class = "zio.ZIO"
@@ -12,4 +11,41 @@ private[plugin] object TermsName {
1211
final val ValidateMethodArgsBinding_Method = "validateMethodArgsBinding"
1312
final val MethodIdentity_Class = "bitlap.validation.extension.MethodIdentity"
1413

14+
object SupportAnnotations {
15+
16+
val values: Seq[String] = Seq(
17+
"AssertFalse",
18+
"AssertTrue",
19+
"DecimalMax",
20+
"DecimalMin",
21+
"Digits",
22+
"Future",
23+
"Max",
24+
"Min",
25+
"Past",
26+
"Pattern",
27+
"Size",
28+
"Email",
29+
"NotBlank",
30+
"PastOrPresent",
31+
"FutureOrPresent",
32+
"NotEmpty",
33+
"Negative",
34+
"NegativeOrZer",
35+
"Positive",
36+
"PositiveOrZero",
37+
"CreditCardNumber",
38+
"EAN",
39+
"Length",
40+
"LuhnCheck",
41+
"Mod10Check",
42+
"Mod11Check",
43+
"NotEmpty",
44+
"Range",
45+
"URL",
46+
"NotNull"
47+
).map(a => s"jakarta.validation.constraints.$a") ++
48+
Seq("AssertNone", "AssertSome", "ByteSize").map(a => s"bitlap.validation.$a") ++
49+
Seq("jakarta.validation.Valid")
50+
}
1551
}

validation-scala-plugin/src/main/scala/bitlap/validation/plugin/ValidationMethodArgsPhase.scala

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import dotty.tools.dotc.core.StdNames.nme
1515
import dotty.tools.dotc.core.Symbols.*
1616
import dotty.tools.dotc.core.Types.{ Type, * }
1717
import dotty.tools.dotc.plugins.PluginPhase
18+
import dotty.tools.dotc.printing.Printer
1819
import dotty.tools.dotc.report
1920
import dotty.tools.dotc.transform.*
2021

@@ -25,10 +26,6 @@ final class ValidationMethodArgsPhase extends PluginPhase:
2526
override val runsAfter: Set[String] = Set(Staging.name)
2627
override val runsBefore: Set[String] = Set(PickleQuotes.name)
2728

28-
@threadUnsafe private lazy val ValidatedAnnotationClass: Context ?=> ClassSymbol = requiredClass(
29-
TermsName.Validated_Annotation
30-
)
31-
3229
@threadUnsafe private lazy val PreconditionsClass: Context ?=> TermSymbol = requiredModule(
3330
TermsName.Preconditions_Class
3431
)
@@ -54,14 +51,21 @@ final class ValidationMethodArgsPhase extends PluginPhase:
5451
return tree
5552
}
5653

57-
// to determine if there are main scala annotations
58-
val optAnnotations = tree.symbol.annotations.collectFirst {
59-
case annotation if annotation.symbol.name.asSimpleName == ValidatedAnnotationClass.name.asSimpleName =>
60-
report.debugwarn(s"Validation found: ${TermsName.Validated_Annotation} on method: ${tree.name.show}")
61-
ValidatedAnnotationClass
54+
val constraintAnnotations =
55+
tree.termParamss
56+
.flatMap(_.flatMap(_.mods.annotations.map(_.symbol.showFullName.stripSuffix(".<init>"))))
57+
58+
val existsAnnotations = constraintAnnotations.collect {
59+
case a if TermsName.SupportAnnotations.values.contains(a) =>
60+
a
6261
}
63-
if optAnnotations.isEmpty then return tree
64-
val bindOpt = tree.termParamss.flatten.find(_.tpt.symbol.showFullName == TermsName.BindingResult_Class)
62+
63+
if (existsAnnotations.isEmpty) return tree
64+
65+
// to determine if there are main scala annotations
66+
report.debugwarn(s"Validation found: ${existsAnnotations.mkString(",")}")
67+
68+
val bindOpt = tree.termParamss.flatten.find(_.tpt.symbol.showFullName == TermsName.BindingResult_Class)
6569

6670
mapDefDef(tree, bindOpt)
6771
}

0 commit comments

Comments
 (0)