Creare parti di DSL come Quickfix dalla grammatica xtext

1

Attualmente sto sperimentando con DSL con xtext. Voglio implementare una soluzione rapida per il dsl che sto scrivendo e mi chiedo, se c'è una possibilità in xtext o xtend hook (o qualcos'altro) di generare un codice frammento dsl dalla grammatica DSL e un dato nodo Ecore .

Ad esempio

Model:
  entities+=Entity*;

Entity:
  'entity' name = ID  ('extends' superType=[Entity])? '{' 
        attributes += Attribute* 
  '}';

Convinco che il Supertipo potrebbe non esistere e voglio suggerire un Quickfix (Ctrl + 1) per creare una nuova Entità. So come fare la parte di validazione e sapere dove implementare il quickfix. Ma dal momento che il DSL è in fase di sviluppo, non voglio scrivere due generatori di codice (uno per la creazione di codice DSL e il secondo per il codice derivato dal modello) poiché il DSL è soggetto a modifiche. Immagino che potrebbe esserci una soluzione più generale, dal momento che la grammatica è nota, a causa della definizione della grammatica xtext e del nodo Ecore che voglio creare, il cui nome conosco dal validatore. Immagino anche che non sia l'unico a fornire una tale "caratteristica" e quindi presumo che ci sia già una soluzione che non ho ancora trovato.

La mia domanda, c'è un modo generico in xtext / xtend di costruire un nodo ecore o AST e serializzare quello AST di nuovo in DSL basato su xtext usando la grammatica xtext?

    
posta thepacker 04.10.2015 - 20:39
fonte

1 risposta

1

Sì, c'è esattamente questo. Puoi fornire il tuo quickfix come una modifica semantica alla risorsa EMF. Il meccanismo di serializzazione di Xtext comprenderà come convertire le tue modifiche in AST in testo.

Qualcosa lungo queste linee dovrebbe fare il trucco:

@Fix(MISSING_SUPERTYPE_ID)
public void fixupSupertype(final Issue issue, IssueResolutionAcceptor acceptor) {
    acceptor.accept(issue, "label", "description", null, new ISemanticModification() {
        @Override
        public void apply(EObject element, IModificationContext context) {
            Model model = (Model)element.eResource().getContents().get(0);
            Entity newEntity = MyDslFactory.eInstance().createEntity()
            model.getEntities().add(newEntity);
            ((Entity)element).setSuperType(newEntity);
        }
    });
}
    
risposta data 05.10.2015 - 14:21
fonte

Leggi altre domande sui tag