Search in sources :

Example 1 with IFeatureInfo

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;
}
Also used : IConstraintElement(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraintElement) ValueTransient(org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient) IAstRegion(org.eclipse.xtext.formatting2.regionaccess.IAstRegion) EStructuralFeature(org.eclipse.emf.ecore.EStructuralFeature) IFeatureInfo(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo)

Example 2 with IFeatureInfo

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;
}
Also used : AbstractElement(org.eclipse.xtext.AbstractElement) EStructuralFeature(org.eclipse.emf.ecore.EStructuralFeature) IConstraint(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraint) IFeatureInfo(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo) IConstraintElement(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraintElement) ISequentialRegion(org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion) IAstRegion(org.eclipse.xtext.formatting2.regionaccess.IAstRegion) ISerializationContext(org.eclipse.xtext.serializer.ISerializationContext) EObject(org.eclipse.emf.ecore.EObject) IHiddenRegion(org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion) EObject(org.eclipse.emf.ecore.EObject) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) EList(org.eclipse.emf.common.util.EList) ListChange(org.eclipse.emf.ecore.change.ListChange) ChangeKind(org.eclipse.emf.ecore.change.ChangeKind)

Example 3 with IFeatureInfo

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());
    }
}
Also used : EClass(org.eclipse.emf.ecore.EClass) IConstraint(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraint) IFeatureInfo(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo)

Example 4 with IFeatureInfo

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;
}
Also used : ValueTransient(org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient) EStructuralFeature(org.eclipse.emf.ecore.EStructuralFeature) IConstraint(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraint) IFeatureInfo(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo)

Example 5 with IFeatureInfo

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;
}
Also used : IConstraintElement(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraintElement) AbstractElement(org.eclipse.xtext.AbstractElement) ISerializationContext(org.eclipse.xtext.serializer.ISerializationContext) IConstraint(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraint) Collection(java.util.Collection) IFeatureInfo(org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo)

Aggregations

IFeatureInfo (org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IFeatureInfo)5 IConstraint (org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraint)4 EStructuralFeature (org.eclipse.emf.ecore.EStructuralFeature)3 IConstraintElement (org.eclipse.xtext.serializer.analysis.IGrammarConstraintProvider.IConstraintElement)3 AbstractElement (org.eclipse.xtext.AbstractElement)2 IAstRegion (org.eclipse.xtext.formatting2.regionaccess.IAstRegion)2 ISerializationContext (org.eclipse.xtext.serializer.ISerializationContext)2 ValueTransient (org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient)2 ImmutableList (com.google.common.collect.ImmutableList)1 Collection (java.util.Collection)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 EList (org.eclipse.emf.common.util.EList)1 EClass (org.eclipse.emf.ecore.EClass)1 EObject (org.eclipse.emf.ecore.EObject)1 ChangeKind (org.eclipse.emf.ecore.change.ChangeKind)1 ListChange (org.eclipse.emf.ecore.change.ListChange)1 IHiddenRegion (org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion)1 ISequentialRegion (org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion)1