Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
Improved custom builder lookup (issue#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcin Kubala committed Sep 27, 2014
1 parent a9bdda2 commit 6f99f7b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.softwaremill.macmemo

import scala.language.experimental.macros

object BuilderResolver {

def resolve(methodFullName: String): MemoCacheBuilder = macro builderResolverMacro_impl

def builderResolverMacro_impl(c: scala.reflect.macros.whitebox.Context)(methodFullName: c.Expr[String]): c.Expr[MemoCacheBuilder] = {
import c.universe._

def bringDefaultBuilder: Tree = {
val Literal(Constant(mfn: String)) = methodFullName.tree
val msg = s"Cannot find custom memo builder for '$mfn' - default builder will be used"
c.info(c.enclosingPosition, msg, false)
reify {
MemoCacheBuilder.guavaMemoCacheBuilder
}.tree
}

val builderTree = c.inferImplicitValue(typeOf[MemoCacheBuilder]) match {
case EmptyTree => bringDefaultBuilder
case foundBuilderTree => foundBuilderTree
}

c.Expr[MemoCacheBuilder](Block(List(), builderTree))
}

}
35 changes: 3 additions & 32 deletions macros/src/main/scala/com/softwaremill/macmemo/memoizeMacro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,6 @@ object memoizeMacro {

val enclosure = c.enclosingClass

def resolveMemoBuilder: Tree = {

def inferImplicitBuilderVal: Tree = {

def findImplicitBuilderVal(body: List[Tree]): Tree =
body.collect {
case v @ ValDef(m, name, _, rhs)
if (m.hasFlag(Flag.IMPLICIT) && c.typecheck(rhs).tpe <:< typeOf[MemoCacheBuilder]) =>
Ident(name)
}.lastOption.getOrElse(EmptyTree)

enclosure match {
case ClassDef(_, _, _, Template(_, _, body)) => findImplicitBuilderVal(body)
case ModuleDef(_, _, Template(_, _, body)) => findImplicitBuilderVal(body)
case oth => EmptyTree
}
}

def bringDefaultBuilder: Tree = {
c.info(c.enclosingPosition, s"Cannot find custom memo builder for method '${cachedMethodId.methodName}' - default builder will be used", false)
reify {
MemoCacheBuilder.guavaMemoCacheBuilder
}.tree
}

c.inferImplicitValue(typeOf[MemoCacheBuilder]) orElse inferImplicitBuilderVal orElse bringDefaultBuilder
}

def buildCacheBucketId: Tree = {
val enclosingClassSymbol = enclosure.symbol
val enclosureFullName = enclosingClassSymbol.fullName + (if (enclosingClassSymbol.isModule) "$." else ".")
Expand All @@ -79,10 +51,9 @@ object memoizeMacro {
q"""com.softwaremill.macmemo.MemoizeParams($maxSize, ${ttl.toMillis}, $concurrencyLevelOpt)"""
}

val t = appliedType(weakTypeOf[Cache[Any]].typeConstructor, typeOf[List[Any]] :: Nil)
ValDef(Modifiers(Flag.LAZY), cachedMethodId.generatedMemoValName, TypeTree(t),
Apply(Select(resolveMemoBuilder, TermName("build")), List(buildCacheBucketId, buildParams))
)
q"""lazy val ${cachedMethodId.generatedMemoValName}: com.softwaremill.macmemo.Cache[List[Any]] =
com.softwaremill.macmemo.BuilderResolver.resolve($buildCacheBucketId).build($buildCacheBucketId, $buildParams)"""

}

def injectCacheUsage(cachedMethodId: MemoIdentifier, function: DefDef) = {
Expand Down

0 comments on commit 6f99f7b

Please sign in to comment.