org.eclipse.xtext.validation.impl.AssignmentQuantityIntervalProvider Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2010 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.xtext.validation.impl;
import java.util.Set;
import org.eclipse.xtext.validation.IConcreteSyntaxConstraintProvider.ISyntaxConstraint;
import org.eclipse.xtext.validation.IAssignmentQuantityIntervalProvider;
import org.eclipse.xtext.validation.IAssignmentQuantityAllocator.IQuantities;
/**
* @author Moritz Eysholdt - Initial contribution and API
*/
public class AssignmentQuantityIntervalProvider implements IAssignmentQuantityIntervalProvider {
protected boolean containsUnavailableFeature(IQuantities ctx, ISyntaxConstraint child, String exclude,
Set involved) {
if (child.isOptional())
return false;
switch (child.getType()) {
case ASSIGNMENT:
if (exclude.equals(child.getAssignmentName()))
return false;
involved.add(child);
return ctx.getAssignmentQuantity(child) == 0;
case GROUP:
for (ISyntaxConstraint a : child.getContents())
if (containsUnavailableFeature(ctx, a, exclude, involved))
return true;
return false;
case ALTERNATIVE:
for (ISyntaxConstraint a : child.getContents())
if (!containsUnavailableFeature(ctx, a, exclude, involved))
return false;
return true;
case ACTION:
if (child.getSemanticTypesToCheck() != null)
return !child.getSemanticTypesToCheck().contains(ctx.getEObject().eClass());
return false;
default:
return false;
}
}
public int getMax(IQuantities ctx, ISyntaxConstraint ass, Set involved, String excludeFeature) {
int c = ass.isRoot() ? 1 : getMaxByParent(ctx, ass.getContainer(), ass, excludeFeature, involved);
return ass.isMultiple() && c > 0 ? MAX : c;
}
protected int getMaxByParent(IQuantities ctx, ISyntaxConstraint ele, ISyntaxConstraint exclude,
String excludeFeature, Set inv) {
int max = ele.isRoot() ? (ele.isMultiple() ? MAX : 1) : getMaxByParent(ctx, ele.getContainer(), ele,
excludeFeature, inv);
if (max == 0)
return 0;
switch (ele.getType()) {
case GROUP:
if (ele.isMultiple())
max = MAX;
if (ele.isOptional() || max == MAX) {
for (ISyntaxConstraint a : ele.getContents())
if (a != exclude) {
int count = getMaxForChild(ctx, a, inv);
if (count != UNDEF && (count < max))
max = count;
}
}
return max == 0 && !ele.isOptional() ? 1 : max;
case ALTERNATIVE:
if (ele.isMultiple())
return MAX;
for (ISyntaxConstraint a : ele.getContents())
if (a != exclude) {
int count = getMinForChild(ctx, a, inv);
if (count > 0)
return 0;
} else if (excludeFeature != null && containsUnavailableFeature(ctx, a, excludeFeature, inv))
return 0;
return max;
default:
return 1;
}
}
protected int getMaxForChild(IQuantities ctx, ISyntaxConstraint child, Set involved) {
if (child.getSemanticTypesToCheck() != null
&& !child.getSemanticTypesToCheck().contains(ctx.getEObject().eClass()))
return 0;
if (child.isOptional())
return MAX;
switch (child.getType()) {
case ASSIGNMENT:
involved.add(child);
return ctx.getAssignmentQuantity(child);
case GROUP:
int count1 = MAX;
for (ISyntaxConstraint a : child.getContents()) {
int c = getMaxForChild(ctx, a, involved);
if (c != UNDEF && c < count1)
count1 = c;
}
return count1;
case ALTERNATIVE:
int count2 = UNDEF;
for (ISyntaxConstraint a : child.getContents()) {
int c = getMaxForChild(ctx, a, involved);
if (c == MAX)
return MAX;
if (c != UNDEF)
count2 = count2 == UNDEF ? c : count2 + c;
}
return count2;
case ACTION:
return MAX;
default:
return UNDEF;
}
}
public int getMin(IQuantities ctx, ISyntaxConstraint assignment, Set involved) {
if (assignment.isOptional())
return 0;
if (assignment.isRoot())
return 1;
return getMinByParent(ctx, assignment.getContainer(), assignment, involved);
}
protected int getMinByParent(IQuantities ctx, ISyntaxConstraint parent, ISyntaxConstraint exclude,
Set involved) {
switch (parent.getType()) {
case GROUP:
if (parent.isRoot() && !parent.isOptional() && !parent.isMultiple())
return 1;
int count1 = UNDEF;
for (ISyntaxConstraint a : parent.getContents())
if (a != exclude) {
int c = getMinForChild(ctx, a, involved);
if (c > count1) {
count1 = c;
break;
}
}
if (parent.isOptional())
return count1 == UNDEF ? 0 : count1;
if (!parent.isRoot())
return Math.max(getMinByParent(ctx, parent.getContainer(), parent, involved), count1);
return UNDEF;
case ALTERNATIVE:
if (parent.isOptional())
return 0;
for (ISyntaxConstraint a : parent.getContents())
if (a != exclude) {
int count2 = getMinForChild(ctx, a, involved);
if (count2 > 0)
return 0;
}
if (!parent.isRoot())
return getMinByParent(ctx, parent.getContainer(), parent, involved);
return 1;
default:
return UNDEF;
}
}
protected int getMinForChild(IQuantities ctx, ISyntaxConstraint child, Set involved) {
if (child.getSemanticTypesToCheck() != null
&& !child.getSemanticTypesToCheck().contains(ctx.getEObject().eClass()))
return 0;
int count = UNDEF;
switch (child.getType()) {
case ASSIGNMENT:
involved.add(child);
count = ctx.getAssignmentQuantity(child);
break;
case GROUP:
for (ISyntaxConstraint a : child.getContents()) {
int c = getMinForChild(ctx, a, involved);
if (c > count)
count = c;
}
break;
case ALTERNATIVE:
for (ISyntaxConstraint a : child.getContents()) {
int c = getMinForChild(ctx, a, involved);
count = count == UNDEF ? c : c + count;
}
break;
case ACTION:
return 1;
}
if (child.isMultiple() && count > 1)
count = 1;
return count;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy