boolean assignment operator not working as expected [message #1808611] |
Thu, 27 June 2019 15:54  |
Eclipse User |
|
|
|
LogicalRealRangeConstraint returns logical::RealRangeConstraint /*hidden (WS)*/:
'rrc' name=ID (description=STRING)? ('('|lowerBoundInclusive?='[') lowerBound=REAL? ':' upperBound=REAL? (')'|upperBoundInclusive?=']')
;
The above rule is one of many in my XText DSL. The syntax ('('|lowerBoundInclusive?='[') is meant to say that if a user specifies '[', then lowerBoundInclusive will be set to true, but if the users specifies '(' then lowerBoundInclusive will be set to false. The syntax (')'|upperBoundInclusive?=']') should do a similar thing for upperBoundInclusive.
This does not appear to work as desired. The syntax does limit the choices for lowerBoundInclusive to either '[' or '(' but lowerBoundInclusive is set to true regardless of which one is used. Similarly for upperBoundInclusive.
What is wrong here?
|
|
|
|
Re: boolean assignment operator not working as expected [message #1808613 is a reply to message #1808612] |
Thu, 27 June 2019 16:06   |
Eclipse User |
|
|
|
There is a custom metamodel that I can't change (it is supplied to me). The defaults in it are true:
/**
*/
package face.v30.face.datamodel.logical.impl;
import face.v30.face.datamodel.logical.LogicalPackage;
import face.v30.face.datamodel.logical.RealRangeConstraint;
import java.lang.Boolean;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Real Range Constraint</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* </p>
* <ul>
* <li>{@link face.v30.face.datamodel.logical.impl.RealRangeConstraintImpl#getLowerBound <em>Lower Bound</em>}</li>
* <li>{@link face.v30.face.datamodel.logical.impl.RealRangeConstraintImpl#getUpperBound <em>Upper Bound</em>}</li>
* <li>{@link face.v30.face.datamodel.logical.impl.RealRangeConstraintImpl#isLowerBoundInclusive <em>Lower Bound Inclusive</em>}</li>
* <li>{@link face.v30.face.datamodel.logical.impl.RealRangeConstraintImpl#isUpperBoundInclusive <em>Upper Bound Inclusive</em>}</li>
* </ul>
*
* @generated
*/
public class RealRangeConstraintImpl extends RealConstraintImpl implements RealRangeConstraint {
/**
* The default value of the '{@link #getLowerBound() <em>Lower Bound</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getLowerBound()
* @generated
* @ordered
*/
protected static final float LOWER_BOUND_EDEFAULT = 0.0F;
/**
* The cached value of the '{@link #getLowerBound() <em>Lower Bound</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getLowerBound()
* @generated
* @ordered
*/
protected float lowerBound = LOWER_BOUND_EDEFAULT;
/**
* The default value of the '{@link #getUpperBound() <em>Upper Bound</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getUpperBound()
* @generated
* @ordered
*/
protected static final float UPPER_BOUND_EDEFAULT = 0.0F;
/**
* The cached value of the '{@link #getUpperBound() <em>Upper Bound</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getUpperBound()
* @generated
* @ordered
*/
protected float upperBound = UPPER_BOUND_EDEFAULT;
/**
* The default value of the '{@link #isLowerBoundInclusive() <em>Lower Bound Inclusive</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isLowerBoundInclusive()
* @generated
* @ordered
*/
protected static final boolean LOWER_BOUND_INCLUSIVE_EDEFAULT = true;
/**
* The cached value of the '{@link #isLowerBoundInclusive() <em>Lower Bound Inclusive</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isLowerBoundInclusive()
* @generated
* @ordered
*/
protected boolean lowerBoundInclusive = LOWER_BOUND_INCLUSIVE_EDEFAULT;
/**
* The default value of the '{@link #isUpperBoundInclusive() <em>Upper Bound Inclusive</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isUpperBoundInclusive()
* @generated
* @ordered
*/
protected static final boolean UPPER_BOUND_INCLUSIVE_EDEFAULT = true;
/**
* The cached value of the '{@link #isUpperBoundInclusive() <em>Upper Bound Inclusive</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isUpperBoundInclusive()
* @generated
* @ordered
*/
protected boolean upperBoundInclusive = UPPER_BOUND_INCLUSIVE_EDEFAULT;
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected RealRangeConstraintImpl() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass() {
return LogicalPackage.Literals.REAL_RANGE_CONSTRAINT;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public float getLowerBound() {
return lowerBound;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void setLowerBound(float newLowerBound) {
float oldLowerBound = lowerBound;
lowerBound = newLowerBound;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND, oldLowerBound, lowerBound));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public float getUpperBound() {
return upperBound;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void setUpperBound(float newUpperBound) {
float oldUpperBound = upperBound;
upperBound = newUpperBound;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND, oldUpperBound, upperBound));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public boolean isLowerBoundInclusive() {
return lowerBoundInclusive;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void setLowerBoundInclusive(boolean newLowerBoundInclusive) {
boolean oldLowerBoundInclusive = lowerBoundInclusive;
lowerBoundInclusive = newLowerBoundInclusive;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND_INCLUSIVE, oldLowerBoundInclusive, lowerBoundInclusive));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public boolean isUpperBoundInclusive() {
return upperBoundInclusive;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void setUpperBoundInclusive(boolean newUpperBoundInclusive) {
boolean oldUpperBoundInclusive = upperBoundInclusive;
upperBoundInclusive = newUpperBoundInclusive;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND_INCLUSIVE, oldUpperBoundInclusive, upperBoundInclusive));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND:
return getLowerBound();
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND:
return getUpperBound();
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND_INCLUSIVE:
return isLowerBoundInclusive();
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND_INCLUSIVE:
return isUpperBoundInclusive();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND:
setLowerBound((Float)newValue);
return;
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND:
setUpperBound((Float)newValue);
return;
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND_INCLUSIVE:
setLowerBoundInclusive((Boolean)newValue);
return;
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND_INCLUSIVE:
setUpperBoundInclusive((Boolean)newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eUnset(int featureID) {
switch (featureID) {
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND:
setLowerBound(LOWER_BOUND_EDEFAULT);
return;
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND:
setUpperBound(UPPER_BOUND_EDEFAULT);
return;
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND_INCLUSIVE:
setLowerBoundInclusive(LOWER_BOUND_INCLUSIVE_EDEFAULT);
return;
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND_INCLUSIVE:
setUpperBoundInclusive(UPPER_BOUND_INCLUSIVE_EDEFAULT);
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public boolean eIsSet(int featureID) {
switch (featureID) {
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND:
return lowerBound != LOWER_BOUND_EDEFAULT;
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND:
return upperBound != UPPER_BOUND_EDEFAULT;
case LogicalPackage.REAL_RANGE_CONSTRAINT__LOWER_BOUND_INCLUSIVE:
return lowerBoundInclusive != LOWER_BOUND_INCLUSIVE_EDEFAULT;
case LogicalPackage.REAL_RANGE_CONSTRAINT__UPPER_BOUND_INCLUSIVE:
return upperBoundInclusive != UPPER_BOUND_INCLUSIVE_EDEFAULT;
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public String toString() {
if (eIsProxy()) return super.toString();
StringBuilder result = new StringBuilder(super.toString());
result.append(" (lowerBound: ");
result.append(lowerBound);
result.append(", upperBound: ");
result.append(upperBound);
result.append(", lowerBoundInclusive: ");
result.append(lowerBoundInclusive);
result.append(", upperBoundInclusive: ");
result.append(upperBoundInclusive);
result.append(')');
return result.toString();
}
} //RealRangeConstraintImpl
|
|
|
|
|
|
|
|
|
Re: boolean assignment operator not working as expected [message #1808632 is a reply to message #1808621] |
Fri, 28 June 2019 01:25   |
Eclipse User |
|
|
|
Hi
I've hit this problem too when I've tried to use a default-true Boolean literal with Xtext. I've had the flexibility to change the metamodel / model reader to workaround the problem. Your less flexible case makes clear that this is arguably an Xtext bug....
An unsettable EMF Boolean has three values internally, true, false, unset. The unset value is only detectable by using eIsSet().
Once a default is supplied, the external view of the Boolean is explicitly-true, explicitly-false, implicitly-default.
The Xtext grammar supports only two values. explicitly-true, implicitly-default.
With a false default, the Xtext grammar gives explicitly-true, implicitly-false which is useable.
With a true default, the Xtext grammar gives explicitly-true, implicitly-true which is not useable.
Therefore the Xtext parser should replace true assignments to Booleans that are default true, with false assignments on all alternative control paths. Or Xtext should support three values ?= for explicitly true, ~= for explicitly false, nothing for default.
(The problem just gets worse if the EMF Boolean is not-unsettable removing the internally unset value).
Regards
Ed Willink
|
|
|
|
Powered by
FUDForum. Page generated in 0.04598 seconds