问题标签 [scala-quasiquotes]

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.

0 投票
1 回答
61 浏览

scala - 如何使用代码模板的 Scala 宏/准引用?

我想在编译时生成一堆遵循简单模式的对象,所以我编写了以下宏:

我不确定 readWrite 和 readWriteImpl 的返回值是否正确——编译器强烈抱怨某些断言失败!

我也不确定如何实际使用这个宏。首先我尝试(在一个单独的编译单元中):

没用。如果我尝试引用 TimeFactories.DurationTypeAdapterFactory ,我会收到一条错误消息,指出找不到它。接下来我想我会尝试将它分配给一个 val ......也没有工作:

我怎样才能把它连接起来,这样我才能得到这样编译的生成代码:

0 投票
1 回答
210 浏览

scala - How does the Scala compiler perform implicit conversion?

I have a custom class, A, and I have defined some operations within the class as follows:

In order to have something like 2.0 + x make sense when x is of type A, I have defined the following implicit class:

This all works fine normally. Now I introduce a compiler plugin with a TypingTransformer that performs some optimizations. Specifically, let's say I have a ValDef:

where x, y, and z are of type A, and a is a Double. Normally, this compiles fine. I put it through the optimizer, which uses quasiquotes to change y + a * z into something else. BUT in this particular example, the expression is unchanged (there are no optimizations to perform). Suddenly, the compiler no longer does an implicit conversion for a * z.

To summarize, I have a compiler plugin that takes an expression that would normally have implicit conversions applied to it. It creates a new expression via quasiquotes, which syntactically appears the same as the old expression. But for this new expression, the compiler fails to perform implicit conversion.

So my question — how does the compiler determine that an implicit conversion must take place? Is there a specific flag or something that needs to be set in the AST that quasiquotes are failing to set?


UPDATE

The plugin phase looks something like this:


UPDATE 2

Please refer to this GitHub repo for a minimum working example: https://github.com/darsnack/compiler-plugin-demo

The issue is that a * z turns into a.<$times: error>(z) after I optimize the statement.

0 投票
1 回答
99 浏览

scala - 如何使用准引号来获取值的类型?

我正在尝试编写以下内容:

本质上,我需要捕获value( Int) in的类型tpe并将其分配给U. 如何做到这一点?

0 投票
2 回答
129 浏览

scala - 如何获得 AST 所代表的值的类型?

我正在尝试编写以下内容:

我需要捕获由 AST 表示的值的类型value并将tpe其分配给U. 如何做到这一点?

编辑:在这里通过准引号为其提供类型注释value和匹配不是一个选项。用例是一个无形可扩展记录,它具有复杂的类型,String with labelled.KeyTag[1, String] :: Long with labelled.KeyTag[three, Long] :: HNil例如val ls = (1 ->> "two") :: ("three" ->> 4L) :: HNil. 此外,valueAST 是以编程方式生成的,而不是文字。

0 投票
1 回答
106 浏览

scala - 由 Scala 宏生成时,依赖类型似乎“不起作用”

为handwavey标题道歉。我不完全确定如何简洁地表达这个问题,因为我以前从未遇到过这样的事情。


背景资料:

我具有以下特征,其中该类型U旨在保存无形可扩展记录类型:

我正在使用黑盒宏(出于此问题范围之外的原因)来创建特征的新实例:


问题:

问题是,当我使用此宏创建 的新实例时Flattened, 的类型fields不再是可扩展记录:


边注:

奇怪的是,如果我手动执行宏的功能,它会起作用:

为什么会有这种差异,我怎样才能让宏版本的行为与手动版本相同?

0 投票
2 回答
624 浏览

string - 将字符串表达式转换为实际工作实例表达式

我正在尝试将 Scala 中作为字符串保存在数据库中的表达式转换回工作代码。

我尝试过 Reflect Toolbox、Groovy 等。但我似乎无法达到我的要求。

这是我尝试过的:

我需要在哪里使用sType实例将 customSchema 传递给 csv 文件以创建数据框,但它似乎失败了。

有什么办法可以让 StructType 的字符串表达式转换为实际的 StructType 实例?任何帮助,将不胜感激。

0 投票
0 回答
49 浏览

scala - 在宏中使用现有方法

假设我有一些带有一些方法的类

我需要重用 someMethod 并覆盖 id 我不知道为什么但它会抛出 Stackoverflow 而且我需要用 Clz 的参数/方法做一些事情而不返回结果

我试过的:

我如何覆盖 Clz 的 id 方法?

为什么它会抛出 StackOverflow?

0 投票
1 回答
631 浏览

scala - 如何获取传递给 Scala 宏的参数的运行时值?

我有一个表面上简单的宏观问题,我一直在努力解决几个小时,但没有运气。也许有更多经验的人可以提供帮助。

我有以下宏:

问题是这样的:我希望宏知道s传递给它的值——不是 的 AST s,而是s自身的值。具体来说,我希望它有这种行为:

保证将传递给的唯一字符串是runTheMacro硬编码的常量值(即,在编译时已知)。

这可能吗,如何做到这一点?

--

编辑:还有以下限制:

  1. 它必须是一个黑盒宏。
  2. 宏签名必须使用c.Trees,而不是c.Expr[_]s(遗留代码;不能更改该部分)
  3. 如果需要,我确实可以使用toolbox宏内部:
0 投票
0 回答
205 浏览

scala - Scala宏:从类类型中获取伴随对象

我无法设法从 Scala 宏/准引号中的类类型中获取伴随对象/单例。尝试遵循https://docs.scala-lang.org/overviews/quasiquotes/type-details.html#singleton-type,给定的示例有效,但它基于一个文字字符串来 quasiquote 直接获取伴随对象,如果我在一些 quasiquote unlifting 之后从提取的参数类类型开始,我将无法完全实现相同的目标。

我已经简化并试图强调预期的用途,以及下面的当前宏实现:

当前的宏实现

编译时的错误是:

错误消息似乎表明该apply方法是在XInner类类型上完成的,而不是XInner.

关于如何获取相同类型名称的组件对象的任何想法?提前致谢!

0 投票
1 回答
59 浏览

scala - 如何使用 scala quasiquotes 动态生成类型应用程序

我想生成一个类型应用程序,这样我就可以调用一个函数,比如foo.bar[com.a.b.SomeType](baz)wherecom.a.b.SomeType可以是多种类型中的任何一种。我在宏运行时使用反射来获取对由 表示的实际类的引用,SomeType因此我可以执行诸如获取包名称、简单名称和完全限定名称之类的操作。

当我写作时,tq"com.a.b.SomeType"我得到了想要的结果,并且可以在我的表达式中使用插值,例如

我需要tq使用可以从宏运行时中从字符串中获取的类信息来动态创建该表达式。我查看了生成的树,每个包 com、a、b、ctq"com.example.SomeType"都有一系列嵌套Select节点,手动生成似乎很麻烦。

我想有一种更简单的方法,我只是没有看到。

为此,我尝试了以下方法:

但我可以看到这是不对的,并得到如下错误:

那么在类型名称只能通过反射获得的情况下,实现我想要做的事情的简洁方法是什么,例如作为Class?