-
Notifications
You must be signed in to change notification settings - Fork 8
Implementing annexes
Global scope must be fully implemented for the annex, delegate to core global scope provider.
The outline tree provider for the annex sublanguage needs to extend from BackgroundOutlineTreeProvider
(not DefaultOutlineTreeProvider
). This allows the outline tree to be build in a separate thread from the UI thread. The main AADL outline tree provider runs in the background, so the annex threads must also.
You need to make sure the label provider for your sublanguage implements ILabelProviderImageDescriptorExtension
. I'm pretty sure this happens for free in Xtext as org.eclipse.xtext.ui.label.AbstractLabelProvider
implements it.
Converting an outline tree provider to extend from BackgroundOutlineTreeProvider
takes a little work because it does not use the PolymorphicDispatcher
hack that DefaultOutlineTreeProvider
uses. Instead its createChildren()
method delegates to a trio of methods:
internalCreateChildren(DocumentRootNode parentNode, EObject modelElement)
internalCreateChildren(EStructuralFeatureNode parentNode, EObject modelElement)
internalCreateChildren(IOutlineNode parentNode, EObject modelElement)
When updating ErrorModelOutlineTreeProvider
, we handled this situation by
- Changing
_createChildren(DocumentRootNode parentNode, EMV2Root emv2Root)
intointernalCreateChildren(DocumentRootNode parentNode, EObject modelElement)
:
protected void _createChildren(DocumentRootNode parentNode, EMV2Root emv2Root) {
if (emv2Root.getLibrary() != null) {
createNode(parentNode, emv2Root.getLibrary());
} else {
emv2Root.getSubclauses().forEach(subclause -> createNode(parentNode, subclause));
}
}
to
protected void internalCreateChildren(final DocumentRootNode parentNode, final EObject modelElement) {
if (modelElement instanceof EMV2Root) {
final EMV2Root emv2Root = (EMV2Root) modelElement;
if (emv2Root.getLibrary() != null) {
createNode(parentNode, emv2Root.getLibrary());
} else {
emv2Root.getSubclauses().forEach(subclause -> createNode(parentNode, subclause));
}
} else {
super.internalCreateChildren(parentNode, modelElement);
}
}
- For all the
_createChildren(IOutlineNode, ...)
methods, we implementedinternalCreateChildren(IOutlineNode parentNode, EObject modelElement)
to perform the polymorphic dispatch tests directly:
@Override
protected void internalCreateChildren(final IOutlineNode parentNode, final EObject modelElement) {
if (parentNode instanceof ErrorPropagationsOutlineNode) {
_createChildren((ErrorPropagationsOutlineNode) parentNode, (ErrorModelSubclause) modelElement);
} else if (parentNode instanceof ComponentErrorBehaviorOutlineNode) {
_createChildren((ComponentErrorBehaviorOutlineNode) parentNode, (ErrorModelSubclause) modelElement);
} else if (parentNode instanceof CompositeErrorBehaviorOutlineNode) {
_createChildren((CompositeErrorBehaviorOutlineNode) parentNode, (ErrorModelSubclause) modelElement);
} else if (parentNode instanceof ConnectionErrorOutlineNode) {
_createChildren((ConnectionErrorOutlineNode) parentNode, (ErrorModelSubclause) modelElement);
} else if (parentNode instanceof PropagationPathsOutlineNode) {
_createChildren((PropagationPathsOutlineNode) parentNode, (ErrorModelSubclause) modelElement);
} else if (parentNode instanceof ErrorTypesOutlineNode) {
_createChildren((ErrorTypesOutlineNode) parentNode, (ErrorModelLibrary) modelElement);
} else {
if (modelElement instanceof DefaultAnnexLibrary) {
_createChildren(parentNode, (DefaultAnnexLibrary) modelElement);
} else if (modelElement instanceof DefaultAnnexSubclause) {
_createChildren(parentNode, (DefaultAnnexSubclause) modelElement);
} else if (modelElement instanceof ErrorModelSubclause) {
_createChildren(parentNode, (ErrorModelSubclause) modelElement);
} else if (modelElement instanceof ErrorBehaviorStateMachine) {
_createChildren(parentNode, (ErrorBehaviorStateMachine) modelElement);
} else if (modelElement instanceof ErrorModelLibrary) {
_createChildren(parentNode, (ErrorModelLibrary) modelElement);
}
}
}
Of course, if the _createChildren()
are very few and very simple, it makes more sense to just inline the methods in to the new internalCreateChildren()
method.
All the _isLeaf()
methods can be merged into the isLeaf()
method:
protected boolean _isLeaf(TypeSet typeSet) {
return true;
}
protected boolean _isLeaf(TypeTransformation typeTransformation) {
return true;
}
protected boolean _isLeaf(TypeMapping typeMapping) {
return true;
}
protected boolean _isLeaf(ErrorPropagation errorPropagation) {
return true;
}
protected boolean _isLeaf(ErrorFlow errorFlow) {
return true;
}
protected boolean _isLeaf(PropagationPath propagationPath) {
return true;
}
protected boolean _isLeaf(ErrorBehaviorEvent errorBehaviorEvent) {
return true;
}
protected boolean _isLeaf(ErrorBehaviorState errorBehaviorState) {
return true;
}
protected boolean _isLeaf(ErrorBehaviorTransition errorBehaviorTransition) {
return true;
}
protected boolean _isLeaf(OutgoingPropagationCondition outgoingPropagationCondition) {
return true;
}
protected boolean _isLeaf(ErrorDetection errorDetection) {
return true;
}
protected boolean _isLeaf(ErrorStateToModeMapping errorStateToModeMapping) {
return true;
}
protected boolean _isLeaf(CompositeState compositeState) {
return true;
}
became
protected boolean isLeaf(final EObject modelElement) {
return modelElement instanceof TypeSet || modelElement instanceof TypeTransformation
|| modelElement instanceof TypeMapping || modelElement instanceof ErrorPropagation
|| modelElement instanceof ErrorFlow || modelElement instanceof PropagationPath
|| modelElement instanceof ErrorBehaviorEvent || modelElement instanceof ErrorBehaviorState
|| modelElement instanceof ErrorBehaviorTransition
|| modelElement instanceof OutgoingPropagationCondition || modelElement instanceof ErrorDetection
|| modelElement instanceof ErrorStateToModeMapping || modelElement instanceof CompositeState;
}