问题标签 [scala-macro-paradise]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scala - Scala 宏注解 - 带类型参数的案例类
我正在尝试为案例类编写一个简单的宏注释,它向伴随对象添加一个方法。问题是新方法必须考虑带注释的案例类的类型参数。
这是我需要通过的测试
这是我为完成此任务而编写的代码
据我了解的问题是,当我尝试类型参数列表提升到生成的语法树中时,它们不会被识别为与原始树中相同的类型参数。
所以我关注的是宏的这一部分
原始语法树发出为
但编译器对此不满意
最终用例是生成涉及超过 1k 行代码的可缓存类型类的实例。非参数化版本已经可以工作了,这只是锦上添花。scalac 的底层有些东西我不明白,但我想。非常感谢您花时间阅读本文。
我正在使用带有宏天堂 2.1.0的 Scala 2.11.8
scala - 在 scala 宏中保留方法参数名称
我有一个界面:
我有一个宏,它迭代接口的方法并使用方法名称和参数进行处理。我通过执行以下操作访问方法名称:
如果我打印出 的doSomething
参数名称,usefulName
则变为x$1
. 为什么会发生这种情况,有没有办法保留原始参数名称?
我正在使用 scala 版本 2.11.8、宏天堂版本 2.1.0 和黑盒上下文。
该接口实际上是我控制的一个单独的 sbt 项目中的 java 源代码。我试过编译:
参数标志应该保留名称,但我仍然得到与以前相同的结果。
scala - Scala 注释宏仅适用于预定义的类
注意:下面有一个编辑! 注意:下面还有另一个编辑!
我编写了一个 Scala 注释宏,它被传递一个类并创建(或更确切地说是填充)一个案例对象。案例对象的名称与传递的类的名称相同。更重要的是,对于传递的类的每一个字段,都会有一个同名的case对象中的字段。但是,case 对象的字段都是 type String
,它们的值是传递的类中相应字段的类型名称。例子:
然而,这似乎只适用于预定义的类,例如String
. 如果我定义 acase class A(...)
并尝试执行@RegisterClass(classOf[A]) case object A
,我会收到以下错误:
我做错了什么?我的宏的代码可以在下面找到。此外,如果有人注意到不惯用的 Scala 或一般的不良做法,我不介意提示。非常感谢您!
编辑:正如 Eugene Burmako 指出的那样,发生错误是因为class A
尚未编译,所以 a java.lang.Class
for 它不存在。我现在已经开始为每个想知道如何让它工作的人提供 100 个 StackOverflow 积分!
编辑 2:用例的一些背景知识:作为我的学士论文的一部分,我正在研究 Scala DSL,用于表达对事件处理系统的查询。这些查询传统上表示为字符串,这会引发很多问题。典型的查询如下所示:“从模式 [A -> B] 中选择 A.id, B.timestamp”。含义:如果一个类型的事件A
发生,然后一个类型的事件也B
发生了,给我事件的和id
事件的。这些类型通常是我无法控制的简单 Java 类。并且是这些类的字段。我希望我的 DSL 查询看起来像这样:. 这意味着对于表示事件类型的每个类,例如,A
timestamp
B
A
B
id
timestamp
select (A.id, B.timestamp) { /* ... * / }
A
,我需要一个伴生对象——最好是同名的。这个伴生对象应该具有与相应类相同的字段,以便我可以将其字段传递给select
函数,如下所示select (A.id, B.timestamp) { /* ... * / }
:这样,如果我试图传递A.idd
给select
函数,如果原始类中没有这样的字段,它将在编译时失败——因为那样的话伴生对象中也不会有这样的字段。
scala - 用户包含 scalamacros 天堂的最简单方法
我刚刚在我的库中添加了一些宏注释。在我的图书馆构建中,我包括
启用宏天堂。
在我的用户使用宏的项目中,我知道他们也需要以scalamacros
某种方式包含在内。现在,在我的示例项目中,我做的和上面一样。我想知道用户是否有更简单或更简单的方式来引入宏?例如,有什么方法可以去掉cross CrossVersion.full
? (因为用户可能没有交叉编译。)
java - Scala 宏找不到 java.util.List、java.lang.Object
更新:有关此问题的解决方案,请参阅下面的答案。还有第二个问题(macro now can't find Pojo),关于第二个问题的问题在这里:Scala macro can't find my java class
我正在创建一个 scala 宏来自动从 POJO 生成案例类(以便更好地使用 avro)。
除了编译器在 java.util.List 和 java.lang.Object 等内置 java 类上阻塞之外,一切都“正常工作”。
我的问题是:如何在宏中生成代码以便编译器解析 java 类?
错误信息示例:
(在 Pojo.java 中没有 // 注释)
(Pojo.java如图)
编辑:showRaw 的结果
showRaw
给出这样的输出,这对我来说看起来不错:
problemdemo/avroschemas/src/main/java/com/squarefoot/Pojo.java
:
problemdemo/src/main/scala/com/squarefoot/converters/problemdemo.scala
:
problemdemo/macros/src/main/scala/com/squarefoot/converters/Caseify.scala
:
sbt 文件:
problemdemo/build.sbt
problemdemo/macros/build.sbt
problemdemo/avroschemas/build.sbt
java - Scala 宏找不到我的 java 类
我正在创建一个 scala 宏来自动从 POJO 生成案例类(以便更好地使用 avro)。
除了编译器(仅在宏扩展期间)阻塞我的 java 类之外,一切都“有效” 。如果我注释掉对宏的调用,一切都编译得很好。
我的问题是:如何在宏中生成代码,以便编译器解析我自己的 java 类?
错误信息示例:
problemdemo/avroschemas/src/main/java/com/squarefoot/Pojo.java
:
problemdemo/src/main/scala/com/squarefoot/converters/problemdemo.scala
:
problemdemo/macros/src/main/scala/com/squarefoot/converters/Caseify.scala
:
sbt 文件:
problemdemo/build.sbt
problemdemo/macros/build.sbt
problemdemo/avroschemas/build.sbt
scala - 如何在宏注释(内联元)中保留糖、格式和空格?
我正在将 Scala 函数导出为外部格式。为此,我使用scala.meta
和一个StaticAnnotation
. 就像是:
在ExportFunctions extends StaticAnnotation
函数体的实现中表示为一棵脱糖树:x.max(y)
.
但是,出于文档目的,拥有实际的源代码会更好。或者至少是糖(x max y
)。
有没有办法保留原始格式/糖?
scala - 为什么这个公共字段有一个 PRIVATE 标志?
我正在编写一个 Scala 宏并遍历树以查找类中的非私有字段。
考虑宏查看的这段代码:
我正在遍历这段代码并到达bar
's ValDef
. 它的修饰符中只有两个标志:Flag.PRIVATE
和Flag.LOCAL
.
使用private
修饰符bar
不会改变任何事情。使用protected
修饰符只会添加Flag.PROTECTED
到标志列表中。
我错过了什么?如何区分私有字段和公共字段?
编辑:
以下代码:
既没有Flag.PRIVATE
也没有Flag.LOCAL
,这是有道理的,因为它是一个“全球”公共 val。
我在里面工作的上下文是为wartremover编写一个新的 wart ,它只是Traverser
在扩展宏并遍历代码块时从上下文的宇宙中获取一个。
scala - 引用注释宏生成的方法时,Scaladoc 生成失败
我有两个班,叫他们Foo
和Fizz
。Foo
使用一个被调用的注解宏expand
来为它的一些方法创建别名(实际的实现比创建别名多一点,但简单的版本仍然会出现以下问题)。为简单起见,假设expand
宏简单地获取带注释的类中的所有方法,并制作它们的副本,将“Copy”附加到方法名称的末尾,然后将调用转发给原始方法。
我的问题是,如果我使用expand
宏 on ,它会创建一个名为Foo
的方法的副本,当在另一个类中调用时,一切都会编译但 scaladoc 生成失败,如下所示:Foo#bar
barCopy
barCopy
Fizz
如果我删除标记正在复制的方法的 scaladoc ( Foo#bar
),该sbt doc
命令将再次起作用。就好像 scaladoc 生成器在不使用已启用的宏天堂插件的情况下调用编译器的早期阶段,但如果从有问题的方法中删除文档,它会以某种方式工作。
这是expand
宏:
以及存在于单独项目中的类:
这似乎是一个错误,或者可能是缺少的功能,但是有没有办法为上述类生成 scaladoc 而无需从复制的方法中删除文档?我在 Scala 2.11.8 和 2.12.1 上都试过了。这是一个简单的 sbt 项目,演示了我遇到的问题。
scala - Scalameta:识别特定的注释
我想使用 scalameta 注释宏在 Scala 中自动生成 REST API 模型。具体来说,给定:
我想生成:
我在这里工作:https ://github.com/pathikrit/metarest
具体来说,我正在这样做:
我对以下代码片段不满意:
上面的代码对我拥有的注释进行“字符串”模式匹配。无论如何要重新使用我必须为这些模式匹配的确切注释: