|
| 1 | +package dotty.tools.dotc |
| 2 | +package transform |
| 3 | + |
| 4 | +import core._ |
| 5 | +import ast.tpd._ |
| 6 | +import Contexts.Context |
| 7 | +import SymDenotations._ |
| 8 | +import Symbols.newSymbol |
| 9 | +import Decorators._ |
| 10 | +import Flags._ |
| 11 | +import Names._ |
| 12 | +import Types._ |
| 13 | + |
| 14 | +import DenotTransformers._ |
| 15 | + |
| 16 | +class BeanProperties(thisPhase: DenotTransformer): |
| 17 | + def addBeanMethods(impl: Template)(using Context): Template = |
| 18 | + val origBody = impl.body |
| 19 | + cpy.Template(impl)(body = impl.body.flatMap { |
| 20 | + case v: ValDef => generateAccessors(v) |
| 21 | + case _ => Nil |
| 22 | + } ::: origBody) |
| 23 | + |
| 24 | + def generateAccessors(valDef: ValDef)(using Context): List[Tree] = |
| 25 | + import Symbols.defn |
| 26 | + |
| 27 | + def generateGetter(valDef: ValDef)(using Context) : Tree = |
| 28 | + val prefix = if valDef.symbol.denot.hasAnnotation(defn.BooleanBeanPropertyAnnot) then "is" else "get" |
| 29 | + val meth = newSymbol( |
| 30 | + owner = summon[Context].owner, |
| 31 | + name = prefixedName(prefix, valDef.name), |
| 32 | + flags = Method | Permanent | Synthetic, |
| 33 | + info = MethodType(Nil, valDef.denot.info)) |
| 34 | + .enteredAfter(thisPhase).asTerm |
| 35 | + meth.addAnnotations(valDef.symbol.annotations) |
| 36 | + val body: Tree = ref(valDef.symbol) |
| 37 | + DefDef(meth, body) |
| 38 | + |
| 39 | + def maybeGenerateSetter(valDef: ValDef)(using Context): Option[Tree] = |
| 40 | + Option.when(valDef.denot.asSymDenotation.flags.is(Mutable)) { |
| 41 | + val owner = summon[Context].owner |
| 42 | + val meth = newSymbol( |
| 43 | + owner, |
| 44 | + name = prefixedName("set", valDef.name), |
| 45 | + flags = Method | Permanent | Synthetic, |
| 46 | + info = MethodType(valDef.name :: Nil, valDef.denot.info :: Nil, defn.UnitType) |
| 47 | + ).enteredAfter(thisPhase).asTerm |
| 48 | + meth.addAnnotations(valDef.symbol.annotations) |
| 49 | + def body(params: List[List[Tree]]): Tree = Assign(ref(valDef.symbol), params.head.head) |
| 50 | + DefDef(meth, body) |
| 51 | + } |
| 52 | + |
| 53 | + def prefixedName(prefix: String, valName: Name) = |
| 54 | + (prefix + valName.lastPart.toString.capitalize).toTermName |
| 55 | + |
| 56 | + extension(a: SymDenotation) def isApplicable = a.hasAnnotation(defn.BeanPropertyAnnot) || a.hasAnnotation(defn.BooleanBeanPropertyAnnot) |
| 57 | + |
| 58 | + if valDef.denot.symbol.isApplicable then |
| 59 | + generateGetter(valDef) +: maybeGenerateSetter(valDef) ++: Nil |
| 60 | + else Nil |
| 61 | + end generateAccessors |
0 commit comments