не копаться в деталях DSL, я мог бы написать (based on that example):Как получить тип в Scala AST для подчеркнутого параметра функции лямбда?
def InputLine = rule { Number ~ zeroOrMore("+" ~ Number ~> ((x: Int, y: Int) => x + y)) ~ EOI }
Мне нужно вызвать функцию лямбда из макроса. Scala AST представление состоит в следующем:
List(
ValDef(Modifiers(PARAM), newTermName("x"), TypeTree().setOriginal(Select(Ident(scala), scala.Int)), EmptyTree),
ValDef(Modifiers(PARAM), newTermName("y"), TypeTree().setOriginal(Select(Ident(scala), scala.Int)), EmptyTree))
Важно отметить, что оба х и у имеет типы в AST. Это прекрасно работает.
Следующий шаг заключается в использовании логического вывода типа, а также упростить лямбда следующим образом:
def InputLine = rule { Number ~ zeroOrMore("+" ~ Number ~> ((_:Int) + _)) ~ EOI }
Scala AST для этого лямбда:
List(
ValDef(Modifiers(PARAM | SYNTHETIC), newTermName("x$1"), TypeTree().setOriginal(Select(Ident(scala), scala.Int)), EmptyTree),
ValDef(Modifiers(PARAM | SYNTHETIC), newTermName("x$2"), TypeTree(), EmptyTree))
Обратите внимание, что х $ 2 парам не имеет никакого явного типа. Мне нужно, чтобы вызвать функцию. Где я должен его получить? Решение «просто передать параметр типа Любое функции« не удовлетворяет scalac по мере необходимости Int.
Этот вопрос логически следует за that one.
Код доступен по адресу [email protected].
Я не уверен, что я точно понимаю, что вы просите, но попробовали ли вы проверить тип дерева (или только его часть) с помощью 'c.typeCheck'? –
@TravisBrown Я попробовал. Я не уверен, правильно ли я использую его. Если просто 'c.typeCheck (tree))' где 'tree' является Scala AST, который содержит подчеркнутую lambda, тогда это не поможет. 'println (s" $ {showRaw (c.typeCheck (tree))} ")' не показывает мне тип 'x $ 2'. Могу ли я каким-либо образом получить от 'macros.Context' какие аргументы типов конкретной функции? –
I.e. имеет значение 'val function = Function (List (ValDef (модификаторы (PARAM | SYNTHETIC), newTermName (« x $ 1 »), TypeTree(). setOriginal (Select (Ident (scala), scala.Int)), EmptyTree), ValDef (Модификаторы (PARAM | SYNTHETIC), newTermName («x $ 2»), TypeTree(), EmptyTree)), Apply (Select (Typed (Ident (newTermName («x $ 1»)), TypeTree(). SetOriginal (Select (Ident (идентификатор (newTermName («x $ 2»))))) вызов 'c.inferTypes (function)', который преобразует ' x $ 2' в 'ValDef (модификаторы (PARAM | SYNTHETIC), newTermName (« x $ 2 »), TypeTree(). setOriginal (Select (Ident (scala), scala.Int)), EmptyTree)' –