use of org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo in project xtext-core by eclipse.
the class PartialSerializer method trySerializeSingleValue.
protected List<SerializationStrategy> trySerializeSingleValue(EObject owner, FeatureChange change, IEObjectRegion ownerRegion, IConstraint constraint) {
List<SerializationStrategy> result = Lists.newArrayList();
EStructuralFeature feature = change.getFeature();
IFeatureInfo featureInfo = constraint.getFeatures()[owner.eClass().getFeatureID(feature)];
List<IConstraintElement> assignments = featureInfo.getAssignments();
if (assignments.size() != 1) {
return null;
}
boolean optional = assignments.get(0).isOptional();
IAstRegion featureRegion = findRegion(ownerRegion, change);
ValueTransient valueTransient = transientValues.isValueTransient(owner, feature);
switch(valueTransient) {
case YES:
if (featureRegion != null) {
if (optional) {
result.add(new DeleteRegionStrategy(featureRegion));
} else {
return null;
}
}
break;
case PREFERABLY:
if (featureRegion != null) {
if (optional) {
result.add(new DeleteRegionStrategy(featureRegion));
} else {
SerializationStrategy update = updateSingleValue(owner, feature, featureRegion);
if (update != null) {
result.add(update);
} else {
return null;
}
}
}
break;
case NO:
if (featureRegion == null) {
return null;
}
SerializationStrategy update = updateSingleValue(owner, feature, featureRegion);
if (update != null) {
result.add(update);
} else {
return null;
}
break;
}
return result;
}
use of org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo in project xtext-core by eclipse.
the class PartialSerializer method trySerializeMultiValue.
protected List<SerializationStrategy> trySerializeMultiValue(EObject owner, FeatureChange change, IEObjectRegion ownerRegion, IConstraint constraint) {
EStructuralFeature feature = change.getFeature();
List<SerializationStrategy> result = Lists.newArrayList();
IFeatureInfo featureInfo = constraint.getFeatures()[owner.eClass().getFeatureID(feature)];
List<IConstraintElement> assignments = featureInfo.getAssignments();
if (assignments.size() != 1) {
return null;
}
IConstraintElement assignment = assignments.get(0);
if (!assignment.isMany()) {
return null;
}
List<IAstRegion> originals = findRegions(ownerRegion, change);
EList<ListChange> listChanges = change.getListChanges();
if (listChanges.isEmpty() && originals.isEmpty()) {
ISerializationContext ctx = getSerializationContext(owner);
AbstractElement ins = assignment.getGrammarElement();
IHiddenRegion insertAt = insertionPointFinder.findInsertionPoint(ctx, ownerRegion, ins);
if (insertAt == null) {
return null;
}
for (Object value : (List<?>) owner.eGet(feature)) {
EObject obj = (EObject) value;
ISerializationContext context = getSerializationContext(obj);
result.add(new SerializeRecursiveStrategy(insertAt, obj, context));
}
return result;
}
// ListTransient listTransient = transientValues.isListTransient(owner, feature);
List<Object> modifying = Lists.newArrayList(((List<?>) owner.eGet(feature)));
for (ListChange lc : listChanges) {
ChangeKind kind = lc.getKind();
if (kind == ADD_LITERAL) {
IAstRegion region = originals.get(lc.getIndex());
result.add(new DeleteRegionStrategy(region));
} else if (kind == MOVE_LITERAL || kind == REMOVE_LITERAL) {
if (originals.isEmpty()) {
return null;
}
int index = lc.getIndex();
IHiddenRegion insertAt;
if (index >= originals.size()) {
insertAt = ((ISequentialRegion) originals.get(originals.size() - 1)).getNextHiddenRegion();
} else {
insertAt = ((ISequentialRegion) originals.get(index)).getPreviousHiddenRegion();
}
EObject value = (EObject) modifying.get(index);
modifying.remove(index);
if (kind == REMOVE_LITERAL) {
ISerializationContext context = getSerializationContext(value);
result.add(new SerializeRecursiveStrategy(insertAt, value, context));
} else if (kind == ChangeKind.MOVE_LITERAL) {
int moveToIndex = lc.getMoveToIndex();
IAstRegion source = originals.get(moveToIndex);
result.add(new DeleteRegionStrategy(source));
result.add(new InsertRegionStrategy(insertAt, source));
}
}
}
return result;
}
use of org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo in project xtext-core by eclipse.
the class SequencerDiagnosticProvider method createBacktrackingFailedDiagnostic.
@Override
public ISerializationDiagnostic createBacktrackingFailedDiagnostic(SerializableObject sem, ISerializationContext ctx, IConstraint constraint) {
EClass type = constraint.getType();
List<String> hints = Lists.newArrayList();
for (IFeatureInfo feature : constraint.getFeatures()) {
int featureID = type.getFeatureID(feature.getFeature());
int count = sem.getValueCount(featureID);
String name = feature.getFeature().getEContainingClass().getName() + "." + feature.getFeature().getName();
if (!sem.isOptional(featureID)) {
int upperBound = feature.getUpperBound();
if (count > upperBound) {
if (feature.getFeature().isMany()) {
hints.add(name + " violates the upper bound: It holds " + count + " values, but only " + upperBound + " are allowed.");
} else {
hints.add(name + " is not allowed to have a value, but it does.");
}
}
}
int lowerBound = feature.getLowerBound();
if (count < lowerBound) {
if (feature.getFeature().isMany()) {
hints.add(name + " violates the lower bound: It holds " + count + " values, but at least " + lowerBound + " are required.");
} else {
hints.add(name + " is required to have a value, but it does not.");
}
}
}
if (!hints.isEmpty()) {
StringBuilder msg = new StringBuilder();
msg.append("Could not serialize " + type.getName() + ":\n");
msg.append(Joiner.on("\n").join(hints));
return new SerializationDiagnostic(BACKTRACKING_FAILED, sem.getEObject(), ctx, grammarAccess.getGrammar(), msg.toString());
} else {
StringBuilder msg = new StringBuilder();
msg.append("Could not serialize " + type.getName() + " via backtracking.\n");
msg.append("Constraint: " + constraint + "\n");
msg.append(sem.getValuesString());
return new SerializationDiagnostic(BACKTRACKING_FAILED, sem.getEObject(), ctx, grammarAccess.getGrammar(), msg.toString());
}
}
use of org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo in project xtext-core by eclipse.
the class ContextFinder method isValidValueQuantity.
protected boolean isValidValueQuantity(IConstraint constraint, EObject semanicObj) {
if (constraint == null)
return false;
for (int featureID = 0; featureID < semanicObj.eClass().getFeatureCount(); featureID++) {
IFeatureInfo featureInfo = constraint.getFeatures()[featureID];
EStructuralFeature feature = semanicObj.eClass().getEStructuralFeature(featureID);
if (feature.isMany()) {
int count = transientValueUtil.countNonTransientListValues(semanicObj, feature);
if (count > featureInfo.getUpperBound())
return false;
if (count < featureInfo.getLowerBound())
return false;
} else {
ValueTransient valueTransient = transientValues.isValueTransient(semanicObj, feature);
switch(valueTransient) {
case NO:
if (featureInfo == null)
return false;
if (featureInfo.getUpperBound() <= 0)
return false;
break;
case YES:
if (featureInfo == null)
break;
if (featureInfo.getLowerBound() > 0)
return false;
break;
case PREFERABLY:
break;
}
}
}
return true;
}
use of org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo in project xtext-core by eclipse.
the class ContextFinder method collectAssignments.
protected Multimap<AbstractElement, ISerializationContext> collectAssignments(Multimap<IConstraint, ISerializationContext> constraints, EStructuralFeature feature) {
Multimap<AbstractElement, ISerializationContext> result = ArrayListMultimap.create();
for (Entry<IConstraint, Collection<ISerializationContext>> e : constraints.asMap().entrySet()) {
IConstraint constraint = e.getKey();
Collection<ISerializationContext> contexts = e.getValue();
IFeatureInfo featureInfo = constraint.getFeatures()[constraint.getType().getFeatureID(feature)];
List<IConstraintElement> assignments = featureInfo.getAssignments();
for (IConstraintElement assignment : assignments) {
result.putAll(assignment.getGrammarElement(), contexts);
}
}
return result;
}
Aggregations