2015-06-23 5 views
1

У меня есть эта грамматика:XText связи услуги и произведенное состояние

Feature returns ecore::EStructuralFeature: 
{Feature} name=ID ':' (fp_many?='*')? eType=[ecore::EClassifier]; 

И в EClass:

Class returns ecore::EClass: 
{EClassClass} 
name=ID (interface?=':Api')? 
(BEGIN 
(eStructuralFeatures+=Feature)* 
(eOperations+=Operation)* 
END)?; 

Моя цель состоит, чтобы иметь DSL для текстуальной Ecore мм с YAML подобного синтаксиса , поэтому мне нужно преобразовать объект Feature в зависимости от его EType либо в атрибут EA, либо в EReference.

Я попытался зацепить afterModelLinked в LazyLinker так:

Queue<Feature> ftrs = Queues.newArrayDeque(features); 
Feature f = null; 
while ((f = ftrs.poll()) != null) { 
    if (f.getEType() == null) 
    continue; 
    if (f.getEType() instanceof EDataType) { 
    createEAttribute(eClazz, f); 
    } else if (f.getEType() instanceof EClass) { 
    createEReference(eClazz, f); 
    } 
    eClazz.getEStructuralFeatures().remove(f); 
} 

Этот код делает преобразует функцию соответствующего типа, но я получаю сообщение об ошибке с сервисом проверки здесь трассировки стека:

org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException 
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:233) 
at org.eclipse.xtext.resource.persistence.StorageAwareResource.getEObject(StorageAwareResource.java:124) 
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.doResolveLazyCrossReference(LazyLinkingResource.java:192) 
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReference(LazyLinkingResource.java:151) 
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReferences(LazyLinkingResource.java:137) 
at org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences(EcoreUtil2.java:528) 
at org.eclipse.xtext.validation.ResourceValidatorImpl.resolveProxies(ResourceValidatorImpl.java:163) 
at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:75) 
at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:91) 
at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:1) 
at org.eclipse.xtext.util.concurrent.CancelableUnitOfWork.exec(CancelableUnitOfWork.java:26) 
at org.eclipse.xtext.resource.OutdatedStateManager.exec(OutdatedStateManager.java:121) 
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.internalReadOnly(XtextDocument.java:520) 
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.readOnly(XtextDocument.java:492) 
at org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:133) 
at org.eclipse.xtext.ui.editor.validation.ValidationJob.createIssues(ValidationJob.java:86) 
at org.eclipse.xtext.ui.editor.validation.ValidationJob.run(ValidationJob.java:67) 
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54) 
Caused by: java.lang.NullPointerException 
at org.eclipse.xtext.linking.impl.ImportedNamesAdapter.find(ImportedNamesAdapter.java:34) 
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getImportedNamesAdapter(DefaultLinkingService.java:95) 
at com.eacg.dsl.faml.linker.FamlLinkingService.getImportedNamesAdapter(FamlLinkingService.java:53) 
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:86) 
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:90) 
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:80) 
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getScope(DefaultLinkingService.java:58) 
at com.eacg.dsl.faml.linker.FamlLinkingService.getScope(FamlLinkingService.java:47) 
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getLinkedObjects(DefaultLinkingService.java:119) 
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:250) 
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:225) 

При отладке я обнаружил, что он все еще использует в контексте объект Feature, даже если я удалил его при создании сопоставления.

Мой вопрос:: Как безопасно заменить объект Feature без развращения моей модели. Я также попытался реализовать IDerivedStateComputer, но получил некоторую ошибку.

+0

Возможно, посмотрите на xcore, который может уже делать то, что вы хотите, а если нет, то можно использовать для создания чего-то, что делает. Для этого лучше явно указать желаемую модель, а затем преобразовать в нее модель уровня xtext, а не изменять на месте. – soru

+0

Спасибо за подсказку, но моя цель - DSL для Ecore MM –

+0

Хотя, если есть какие-то полезные предложения, я открыт, если есть лучший способ добиться этого. –

ответ

2

Я думаю, что основная проблема заключается в том, что EMF представляет собой графический формат; классы могут быть функциями других классов, аргументами для операций и т. д. В общем, этот график отношений может содержать циклы, циклы и узлы. Таким образом, все, что пытается изменить ситуацию на месте, будет сложным, требующим полномасштабного алгоритма обхода графика, чтобы убедиться, что вы не меняете что-то, на что-то, что вы еще не обработали.

Альтернативой является то, что модель загружает и связывает в своей родной форме, а затем преобразует ее как один проход. Это способ xcore реализует вещи; эквивалентная декларация:

XClass: 
{XClass} 
(annotations+=XAnnotation)* 
((abstract?='abstract'? 'class') | interface?= 'interface') name = ID 
('<' typeParameters+=XTypeParameter (',' typeParameters+=XTypeParameter)* '>')? 
('extends' superTypes+=XGenericType (',' superTypes+=XGenericType)*)? 
('wraps' instanceType=JvmTypeReference) ? 
'{' 
    (members+=XMember)* 
'}' 

;

Обратите внимание на все X, это локальные классы моделей. Затем будет только функция:

protected EClass getEClass(final XClass xClass) 
+0

Да, вы правы в том, что «альтернатива заключается в том, чтобы загрузить модель и связать ее в своей родной форме, а затем преобразовать ее в один проход». Я буду копаться на этом, но я не хочу использовать Xcore, так как это не то, что я хочу достичь, я хочу Ecore DSL. –

+0

Я приму это как отличный намек –