[grammar] Report error in grammar when assigning unchangeable feature

https://bugs.eclipse.org/bugs/show_bug.cgi?id=350747
This commit is contained in:
Jan Koehnlein 2012-02-24 15:59:16 +01:00
parent f78d7f058b
commit ca02badc3a
2 changed files with 70 additions and 46 deletions

View file

@ -181,53 +181,58 @@ public abstract class EClassifierInfo {
StringBuilder errorMessage) {
EStructuralFeature assignedExistingFeature = getEClass().getEStructuralFeature(name);
if (assignedExistingFeature != null) {
boolean many = assignedExistingFeature.isMany();
if (many == isMulti) {
if (expectedType instanceof EClass && assignedExistingFeature.getEType() instanceof EClass) {
EClass castedExpectedType = (EClass) expectedType;
EClass castedExistingType = (EClass) assignedExistingFeature.getEType();
boolean result = isAssignableFrom(castedExistingType, castedExpectedType);
if (!result) {
// TODO check for same name / nsURI pair but different resource uris
errorMessage.append("The existing reference '" + name + "' has an incompatible type " + classifierToString(castedExistingType) + ". " +
"The expected type is " + classifierToString(castedExpectedType) + ".");
return result;
}
result &= isContainment == ((EReference) assignedExistingFeature).isContainment();
if (!result) {
if (isContainment)
errorMessage.append("The existing reference '" + name + "' is not a containment reference.");
else
errorMessage.append("The existing reference '" + name + "' is a containment reference.");
return result;
}
result &= !((EReference) assignedExistingFeature).isContainer();
if (!result) {
errorMessage.append("The existing reference '" + name + "' is a container reference.");
return result;
}
return result;
} else if (expectedType instanceof EDataType && assignedExistingFeature.getEType() instanceof EDataType) {
EDataType castedExpectedType = (EDataType) expectedType;
EDataType castedExistingType = (EDataType) assignedExistingFeature.getEType();
Class<?> expectedInstanceClass = ReflectionUtil.getObjectType(castedExpectedType.getInstanceClass());
Class<?> existingInstanceClass = ReflectionUtil.getObjectType(castedExistingType.getInstanceClass());
boolean result = castedExistingType.equals(castedExpectedType) || expectedInstanceClass != null && existingInstanceClass != null
&& existingInstanceClass.isAssignableFrom(expectedInstanceClass);
if (!result) {
errorMessage.append("The existing attribute '" + name + "' has an incompatible type " + classifierToString(castedExistingType) + ". " +
"The expected type is " + classifierToString(castedExpectedType) + ".");
}
return result;
} else {
String msgPart = " has no type.";
if (assignedExistingFeature.getEType() != null)
msgPart = " has an incompatible type " + classifierToString(assignedExistingFeature.getEType())+ ". " +
"The expected type is " + classifierToString(expectedType) + ".";
errorMessage.append("The existing feature '" + name + "'" + msgPart);
}
if (!assignedExistingFeature.isChangeable()) {
errorMessage.append("The existing feature '" + name + "' is not changeable.");
return false;
} else {
errorMessage.append("The existing feature '" + name + "' has a different cardinality.");
boolean many = assignedExistingFeature.isMany();
if (many == isMulti) {
if (expectedType instanceof EClass && assignedExistingFeature.getEType() instanceof EClass) {
EClass castedExpectedType = (EClass) expectedType;
EClass castedExistingType = (EClass) assignedExistingFeature.getEType();
boolean result = isAssignableFrom(castedExistingType, castedExpectedType);
if (!result) {
// TODO check for same name / nsURI pair but different resource uris
errorMessage.append("The existing reference '" + name + "' has an incompatible type " + classifierToString(castedExistingType) + ". " +
"The expected type is " + classifierToString(castedExpectedType) + ".");
return result;
}
result &= isContainment == ((EReference) assignedExistingFeature).isContainment();
if (!result) {
if (isContainment)
errorMessage.append("The existing reference '" + name + "' is not a containment reference.");
else
errorMessage.append("The existing reference '" + name + "' is a containment reference.");
return result;
}
result &= !((EReference) assignedExistingFeature).isContainer();
if (!result) {
errorMessage.append("The existing reference '" + name + "' is a container reference.");
return result;
}
return result;
} else if (expectedType instanceof EDataType && assignedExistingFeature.getEType() instanceof EDataType) {
EDataType castedExpectedType = (EDataType) expectedType;
EDataType castedExistingType = (EDataType) assignedExistingFeature.getEType();
Class<?> expectedInstanceClass = ReflectionUtil.getObjectType(castedExpectedType.getInstanceClass());
Class<?> existingInstanceClass = ReflectionUtil.getObjectType(castedExistingType.getInstanceClass());
boolean result = castedExistingType.equals(castedExpectedType) || expectedInstanceClass != null && existingInstanceClass != null
&& existingInstanceClass.isAssignableFrom(expectedInstanceClass);
if (!result) {
errorMessage.append("The existing attribute '" + name + "' has an incompatible type " + classifierToString(castedExistingType) + ". " +
"The expected type is " + classifierToString(castedExpectedType) + ".");
}
return result;
} else {
String msgPart = " has no type.";
if (assignedExistingFeature.getEType() != null)
msgPart = " has an incompatible type " + classifierToString(assignedExistingFeature.getEType())+ ". " +
"The expected type is " + classifierToString(expectedType) + ".";
errorMessage.append("The existing feature '" + name + "'" + msgPart);
}
} else {
errorMessage.append("The existing feature '" + name + "' has a different cardinality.");
}
}
} else {
errorMessage.append("The type '" + getEClass().getName() + "' does not have a feature '" + name + "'.");

View file

@ -10,6 +10,8 @@ package org.eclipse.xtext.xtext.ecoreInference;
import java.util.Collections;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.xtext.xtext.ecoreInference.EClassifierInfo.EClassInfo;
import org.junit.Assert;
@ -37,6 +39,23 @@ public class EClassInfoTest extends Assert {
assertEquals(false,objectUnderTest.containsCompatibleFeature("eStructuralFeatures", true, true, pack.getEAnnotation(), new StringBuilder()));
}
public void testChangeable(){
EcorePackage pack = EcorePackage.eINSTANCE;
EClass eClass = pack.getEClass();
EClassInfo objectUnderTest = new EClassifierInfo.EClassInfo(eClass, false, Collections.<String>emptySet(), null);
EcoreFactory fac = EcoreFactory.eINSTANCE;
EReference reference = fac.createEReference();
reference.setName("newReference");
reference.setEType(eClass);
reference.setChangeable(true);
reference.setContainment(true);
eClass.getEStructuralFeatures().add(reference);
assertEquals(true,objectUnderTest.containsCompatibleFeature("newReference", false, true, eClass, new StringBuilder()));
reference.setChangeable(false);
assertEquals(false,objectUnderTest.containsCompatibleFeature("newReference", false, true, eClass, new StringBuilder()));
}
@Test public void testContainsCompatibleFeature_02() throws Exception {
EcorePackage pack = EcorePackage.eINSTANCE;
EClass attribute = pack.getEAttribute();