In un plugin per compilatore Scala, sto provando a creare una nuova classe che implementa un tratto preesistente. Finora il mio codice assomiglia a questo:Come aggiungere una nuova classe in un plugin per compilatore Scala?
def trait2Impl(original: ClassDef, newName: String): ClassDef = {
val impl = original.impl
// Seems OK to have same self, but does not make sense to me ...
val self = impl.self
// TODO: implement methods ...
val body = impl.body
// We implement original
val parents = original :: impl.parents
val newImpl = treeCopy.Template(impl, parents, self, body)
val name = newTypeName(newName)
// We are a syntheic class, not a user-defined trait
val mods = (original.mods | SYNTHETIC) &~ TRAIT
val tp = original.tparams
val result = treeCopy.ClassDef(original, mods, name, tp, newImpl)
// Same Package?
val owner = original.symbol.owner
// New symbol. What's a Position good for?
val symbol = new TypeSymbol(owner, NoPosition, name)
result.setSymbol(symbol)
symbol.setFlag(SYNTHETIC)
symbol.setFlag(ABSTRACT)
symbol.resetFlag(INTERFACE)
symbol.resetFlag(TRAIT)
owner.info.decls.enter(symbol)
result
}
Ma non sembra essere aggiunto al pacchetto. Sospetto che sia perché effettivamente il pacchetto è "attraversato" prima del tratto che causa la generazione, e/o perché il metodo "override def transform (tree: Tree): Tree" di TypingTransformer può restituire solo un albero ogni albero che riceve, quindi non può effettivamente produrre un nuovo albero, ma modificarne solo uno.
Quindi, come si aggiunge una nuova classe a un pacchetto esistente? Forse funzionerebbe se trasformassi il pacchetto quando "transform (Tree)" lo ottiene, ma io quel punto non conosco ancora il contenuto del pacchetto, quindi non posso generare la nuova classe così presto (o potrei?) . O forse è legato al parametro "Posizione" del Simbolo?
Finora ho trovato diversi esempi in cui gli alberi vengono modificati, ma nessuno in cui una classe completamente nuova viene creata in un plug-in compilatore.
avete risolto il problema? Ne sto avendo uno simile, quindi mi stavo chiedendo ... Penso che sia necessario abbinare per il genitore della tua caratteristica nel metodo di trasformazione, sfortunatamente. Cioè, fai attenzione a PackageDef e Template e trova tutte le occorrenze del tuo tratto nei loro corpi. Quindi puoi restituire un PackageDef e un Template trasformati. –
Sì, ho ricevuto l'aiuto da una mailing list di Scala. Ma non ci sono ancora, dato che posso solo creare la classe in * lo stesso pacchetto *. Cercherò di pubblicare una risposta alla mia domanda quando avrò risolto le cose. –
Per favore rispondi alla tua domanda ORA! Perché ho la stessa [domanda] (https://github.com/iron9light/autoguice) – iron9light