mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-17 01:08:56 +00:00
[grammar] Report error in grammar when assigning unchangeable feature
https://bugs.eclipse.org/bugs/show_bug.cgi?id=350747
This commit is contained in:
parent
f78d7f058b
commit
ca02badc3a
2 changed files with 70 additions and 46 deletions
|
@ -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 + "'.");
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue