Я пишу плагин компилятора, который переводит подмножество Scala в C ++ (игнорируйте очевидное безумие этой задачи). Я использую несколько плагинов, которые должны запускаться после фазы стирания. Тем не менее, мне требуется полная информация о типе для вывода действительного кода.
Например, для Скалы;
def foo(f: Type1 => Type2): Unit = { /* Snip */ }
Я хотел бы вывести C ++;
void foo(scala::Function1<Type1, Type2> f) { /* Snip */ }
Тем не менее, после фазы стирания, foo
выглядит так:
def foo(f: Function1): Unit = { /* Snip */ }
То есть, общая информация о типе для параметра, f
был потерян. Мне нужно вернуть его как-нибудь. Какие-либо предложения?
Ответить на комментарий cdshines
Вот пример:
example.scala
object Example {
def func(f: Int => Boolean) { }
}
Когда я компилирую;
# scalac -version
Scala compiler version 2.9.3 -- Copyright 2002-2011, LAMP/EPFL
# scalac -Xprint:explicitouter -Xprint:erasure example.scala
[[syntax trees at end of explicitouter]]// Scala source: example.scala
package <empty> {
final object Example extends java.lang.Object with ScalaObject {
def this(): object Example = {
Example.super.this();
()
};
def func(f: Int => Boolean): Unit = ()
}
}
[[syntax trees at end of erasure]]// Scala source: example.scala
package <empty> {
final object Example extends java.lang.Object with ScalaObject {
def this(): object Example = {
Example.super.this();
()
};
def func(f: Function1): Unit = ()
}
}
Обратите внимание на изменение подписи func
, explicitouter
фаза до erasure
,
Это решение было предложено списком рассылки на языке scala. Внутри что-то, что импортирует scala.tools.nsc.Global
пространство имен, следующий будет восстанавливать тип метода (более конкретно DefDef
в АСТ) до erasure
фаза.
atPhase(currentRun.erasurePhase) { someDefDef.symbol.tpe }
Других решений пока нет …