From 77e153e61a96464512f973b1e61a955dbf29dce4 Mon Sep 17 00:00:00 2001 From: Moritz Eysholdt Date: Tue, 20 Oct 2015 21:34:30 +0200 Subject: [PATCH] [serializer] check value ranges properly to determine context Signed-off-by: Moritz Eysholdt --- .../serializer/sequencer/ContextFinder.java | 47 +++++++++++-------- .../sequencer/TransientValueUtil.java | 17 +++++++ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/ContextFinder.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/ContextFinder.java index 6dd7c003e..86fa7b668 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/ContextFinder.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/ContextFinder.java @@ -162,7 +162,8 @@ public class ContextFinder implements IContextFinder { } @Override - public Set findByContentsAndContainer(EObject semanticObject, Iterable contextCandidates) { + public Set findByContentsAndContainer(EObject semanticObject, + Iterable contextCandidates) { initConstraints(); contextCandidates = findContextsByContainer(semanticObject, contextCandidates); if (contextCandidates != null && Iterables.size(contextCandidates) < 2) @@ -225,8 +226,7 @@ public class ContextFinder implements IContextFinder { @Override @Deprecated - public Iterable findContextsByContentsAndContainer(EObject semanticObject, - Iterable contextCandidates) { + public Iterable findContextsByContentsAndContainer(EObject semanticObject, Iterable contextCandidates) { List candidates = fromEObjects(contextCandidates, semanticObject); return fromIContexts(findByContentsAndContainer(semanticObject, candidates)); } @@ -283,24 +283,31 @@ public class ContextFinder implements IContextFinder { return false; for (int featureID = 0; featureID < semanicObj.eClass().getFeatureCount(); featureID++) { IFeatureInfo featureInfo = constraint.getFeatures()[featureID]; - EStructuralFeature structuralFeature = semanicObj.eClass().getEStructuralFeature(featureID); - // TODO validated bounds of lists properly - ValueTransient trans = transientValueUtil.isTransient(semanicObj, structuralFeature); - switch (trans) { - case NO: - if (featureInfo == null) - return false; - if (featureInfo.getUpperBound() <= 0) - return false; - break; - case YES: - if (featureInfo == null) + 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; - if (featureInfo.getLowerBound() > 0) - return false; - break; - case PREFERABLY: - break; + case YES: + if (featureInfo == null) + break; + if (featureInfo.getLowerBound() > 0) + return false; + break; + case PREFERABLY: + break; + } } } return true; diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/TransientValueUtil.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/TransientValueUtil.java index 07cfe17a0..858d095ba 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/TransientValueUtil.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/serializer/sequencer/TransientValueUtil.java @@ -61,6 +61,23 @@ public class TransientValueUtil { return Collections.emptyList(); } + public int countNonTransientListValues(EObject container, EStructuralFeature feature) { + switch (transientValues.isListTransient(container, feature)) { + case SOME: + int result = 0; + List values = (List) container.eGet(feature); + for (int i = 0; i < values.size(); i++) + if (!transientValues.isValueInListTransient(container, i, feature)) + result++; + return result; + case NO: + return ((List) container.eGet(feature)).size(); + case YES: + return 0; + } + return 0; + } + public ValueTransient isTransient(EObject obj, EStructuralFeature feature) { if (feature.isMany()) switch (transientValues.isListTransient(obj, feature)) {