标签: scala-macros

在selectDynamic的宏实现中调用实例方法

我想Sample#cap(String)在selectDynamic的以下宏实现中使用.

可能吗?

// macro implementation
import scala.language.experimental.macros
import scala.reflect.macros._

object MyMacros {
  def selectDynamic(c: Context)(name: c.Expr[String]): c.Expr[String] = {
    // I expected `This` to refer a Sample instance, but actually it refers SampleSpec instance...
    c.Expr[String](Apply(TypeApply(Select(This(tpnme.EMPTY), newTermName("cap")), List(Ident(typeTag[String].tpe.typeSymbol))), List(name.tree)))
  }
}

// class which uses selectDynamic and macro
import scala.language.dynamics
class Sample extends Dynamic {
  def cap(name: String): String = name.toUpperCase
  def selectDynamic(name: String): String = macro MyMacros.selectDynamic
}

class SampleSpec extends FlatSpec with ShouldMatchers {
  it should "call …
Run Code Online (Sandbox Code Playgroud)

scala scala-macros

3
推荐指数
1
解决办法
724
查看次数

后代类中的宏扩展

我有下一个类结构:

trait SomeType

trait Root {
  val allMySomeTypes: Seq[SomeType]
}

class Child extends Root {
  object MyType1 extends SomeType {...}
  object MyType2 extends SomeType {...}
}
Run Code Online (Sandbox Code Playgroud)

我想初始化val allMySomeTypes作为扩展在具体类中定义的SomeType的所有对象的Seq.所以对于Child实例,它将是val allMySomeTypes:Seq [SomeType] = Seq(MyType1,MyType2).

我写了一个宏来查找具有一些基类型的对象:

def getMembersOfCurrentByType_impl[S](c: Context)(implicit ev: c.WeakTypeTag[S]) = {
  import c.universe._
  val seqApply = Select(reify(Seq).tree, newTermName("apply"))
  val objs = c.enclosingClass.symbol.typeSignature.declarations.collect {
    case o: ModuleSymbol if o.typeSignature <:< ev.tpe => Ident(o) //Select(c.prefix.tree, o)
  }.toList
  c.Expr[Seq[S]] {Apply(seqApply, objs)}
}
Run Code Online (Sandbox Code Playgroud)

并绑定到

trait Root {
  val allMySomeTypes: Seq[SomeType] = macro getMembersOfCurrentByType_impl[SomeType]
}
Run Code Online (Sandbox Code Playgroud)

但是,显然,由于基本特征的宏扩展,我在Child类中有空序列.我可以在没有在Child类中额外输入而不使用运行时反射的情况下构建实际成员的Seq吗?

scala scala-macros

3
推荐指数
1
解决办法
335
查看次数

通用类的scala宏泛型字段不应用类泛型类型参数

通用案例类

case class GroupResult[T](
  group: String,
  reduction: Seq[T]
)
Run Code Online (Sandbox Code Playgroud)

宏观方法

 def foo[T] = macro fooImpl[T]

 def fooImpl[T: c.WeakTypeTag](c: Context) = {
    import c.universe._
    val tpe = weakTypeOf[T]
     tpe.declarations.collect {
      case m: MethodSymbol if m.isCaseAccessor => println(m.returnType)
    }
    c.literalUnit
  }
Run Code Online (Sandbox Code Playgroud)

当我调用 foo[GroupResult[Int]]

输出是

String
Seq[T]
Run Code Online (Sandbox Code Playgroud)

T不适用?我怎样才能获得申请Seq[Int]

generics macros scala scala-macros

3
推荐指数
1
解决办法
566
查看次数

自动为案例类生成案例对象

如何让 Scala 编译器自动生成 case 对象?

// Pizza class
class Pizza (val crust_type: String)

// companion object
object Pizza {
    val crustType = "crust_type"
}
Run Code Online (Sandbox Code Playgroud)

案例对象的所需属性

  • 为每个属性case class生成一个属性case object
  • 设置在每个相应的情况下,对象的属性名称和变化的字符串表示的值camelCasesnake_case该对象的属性名,保持snake_case为对象的属性值

scala case-class companion-object scala-macros scalameta

3
推荐指数
1
解决办法
733
查看次数

Scala:Context.eval 中的代码可以参考什么?

看来 的输入Context.eval只能引用来自不同编译单元的值:

// project 1
object Z {

  val foo = "WOOF"

  def impl(c: Context)(x: c.Expr[String]) = {
    val x1 = c.Expr[String](c.untypecheck(x.tree.duplicate))
    println(s"compile-time value is: ${c.eval(x1)}")
    x
  }
  def test(x: String) = macro impl
}

// project 2
object Y {
  val foo = "GOOF"
  val boo = Z.test(Z.foo)
}


println(Y.boo)
Run Code Online (Sandbox Code Playgroud)

打印出"WOOF",但如果我将 boo 替换为val boo = Z.test(Y.foo),则会出现以下编译错误:

Error:(32, 29) exception during macro expansion:
java.lang.ClassNotFoundException: Y$
at scala.reflect.internal.util.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:72)
...
Run Code Online (Sandbox Code Playgroud)

有什么办法可以解决这个问题吗?我知道用 quill.io 定义的查询可以引用同一范围的方法,但我无法找到他们用来允许它的技巧。

macros scala scala-macros quill.io

3
推荐指数
1
解决办法
317
查看次数

Scala3:通过元编程创建类型?

我正在使用 scala3 进行编码,利用编程结构类型。结构类型恰好模仿了现有的案例类:它们的定义是纯粹的样板,因此很容易通过元编程来制作它们。

我了解如何制作函数实现,通常是通过类型类派生。但在这里我们正在尝试制作一个(结构)类型

这在 scala2 中是可能的,通过类宏注释,但这些在 scala3 中已经消失了。有办法吗?如果是这样怎么办?

下面的代码是我想获得的结果:


// Library part
trait View extends scala.Selectable :
  def selectDynamic(key:String) =
    println(s"$key is being looked up")
    ???


// DSL Definition part
case class SomeDefWithInt   ( i : Int    )
case class SomeDefWithString( s : String )

// Boiler-plate code 
type ViewOf[M] = M match
  case SomeDefWithInt    => View { def i : Int    }
  case SomeDefWithString => View { def s : …
Run Code Online (Sandbox Code Playgroud)

scala metaprogramming scala-macros scala-3

3
推荐指数
1
解决办法
610
查看次数

在Scala中,宏可以自然地进行链式比较吗?

Scala不像Python那样提供链式比较:

// Python:
0 < x <= 3
// Scala:
0 < x && x <= 3
Run Code Online (Sandbox Code Playgroud)

具有新宏功能的Scala 2.10能否让程序员编写一个添加此功能的库?或者这超出了Scala宏的范围?

宏似乎是实现这种语法糖的正确选择,因为它们不会使解析器/编译器复杂化.

comparison scala syntactic-sugar scala-2.10 scala-macros

2
推荐指数
1
解决办法
204
查看次数

使用Scala宏在树中查找所有可能的序列创建

我想使用Scala宏在树中找到所有可能的序列创建.

val l = List(1, 2)
val v = Vector(1, 2)
val ab = ArrayBuffer(1, 2)
val s = Seq(1, 2)
Run Code Online (Sandbox Code Playgroud)

但以下匹配不起作用:

case Apply(TypeApply(Select(path, Name("apply")), _), args) if path.tpe <:< weakTypeOf[SeqFactory[Any]] => ...
Run Code Online (Sandbox Code Playgroud)

同样,我需要通过索引查找序列的所有访问:

val v = Vector(1, 2)
val one = v(0)
Run Code Online (Sandbox Code Playgroud)

或路径上的所有'apply'方法调用,即path.tpe <:<???? [Seq [_]

怎么写这张支票?这不编译:

case Apply(Select(path, Name("apply")), List(idx)) if path.tpe <:< typeOf[Seq[_]]
Run Code Online (Sandbox Code Playgroud)

scala scala-2.10 scala-macros

2
推荐指数
1
解决办法
227
查看次数

宏观依赖性出现在POM/JAR中

我有一个使用宏的scala项目,它基本上遵循这里描述的确切方法(http://www.scala-sbt.org/0.12.4/docs/Detailed-Topics/Macro-Projects.html),包括整个分发部分(所以本质上我有一个根项目,一个名为宏的子项目,用于保存正在使用的宏)

问题是,当我发布我的项目(现在使用publish-local),而另一个scala项目使用带有宏作为依赖项的项目时,它会尝试拉宏#macro_2.10; 0.1-SNAPSHOT因为它出现在POM.这导致项目无法编译,因为它无法解决依赖关系,即

> compile
[info] Updating {file:/Users/mdedetrich/silvermanwylie/waitress/}default-0e4b9d...
[info] Resolving macro#macro_2.10;0.1-SNAPSHOT ...
[warn]  module not found: macro#macro_2.10;0.1-SNAPSHOT
[warn] ==== local: tried
[warn]   /Users/mdedetrich/.ivy2/local/macro/macro_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[warn] ==== public: tried
[warn]   http://repo1.maven.org/maven2/macro/macro_2.10/0.1-SNAPSHOT/macro_2.10-0.1-SNAPSHOT.pom
[info] Resolving org.slf4j#slf4j-api;1.6.4 ...
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: macro#macro_2.10;0.1-SNAPSHOT: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last *:update for the full output.
[error] (*:update) sbt.ResolveException: unresolved dependency: macro#macro_2.10;0.1-SNAPSHOT: not found
[error] Total time: 0 s, completed Aug 23, 2013 8:15:56 …
Run Code Online (Sandbox Code Playgroud)

macros scala pom.xml sbt scala-macros

2
推荐指数
1
解决办法
298
查看次数

Scala Macro Paradise:如何使用宏注释获取注释的参数?

Let's say I wanted to replicate an annotation like @specialized(Int)--crazy I know--using macro annotations. Something like:

class expand(expanded: Any*) extends Annotation with StaticAnnotation {
  def macroTransform(annottees: Any*) = macro expand.expandImpl
}

object expand {
 def expandImpl(c: Context)(annottees: c.Expr[Any]*):c.Expr[Any] = {        
    // would like to be able to get access to the "expanded" args above.
    ???
  }
}

// Usage:
 def foo[@expand(Int) T] = 4
Run Code Online (Sandbox Code Playgroud)

Is there any way to get access to the arguments of the annotation (Int in the …

annotations scala scala-macros

2
推荐指数
1
解决办法
440
查看次数