[454551] Added check for equal classifier ID and namespace URI for better error message when an inconsistent type is found

Change-Id: I28814cfab1ed053d9e594a768acf2bfd6f8d4157
Signed-off-by: Miro Spönemann <miro.spoenemann@itemis.de>
This commit is contained in:
Miro Spönemann 2014-12-15 11:36:30 +01:00
parent bcd60753e6
commit 0ac8ef3ccb
2 changed files with 37 additions and 4 deletions

View file

@ -482,7 +482,7 @@ public class GrammarUtil {
}
/**
* Find the datatype for EBoolean which is referable from the given grammar.
* Find the class for EObject which is referable from the given grammar.
* @since 2.1
*/
public static EClass findEObject(Grammar grammar) {

View file

@ -92,6 +92,10 @@ public abstract class EClassifierInfo {
&& isAssignableFrom(getEClass(),(EClass) subTypeInfo.getEClassifier());
}
/**
* Determine whether the class represented by {@code left} is either the same as
* or is a superclass of the class represented by {@code right}.
*/
protected boolean isAssignableFrom(EClass left, EClass right) {
if (right != null && left.isSuperTypeOf(right))
return true;
@ -197,9 +201,13 @@ public abstract class EClassifierInfo {
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) + ".");
if (isAssignableByID(castedExistingType, castedExpectedType)) {
errorMessage.append("The type " + classifierToString(castedExistingType) + " used in the reference '" + name + "' is inconsistent. " +
"Probably this is due to an unsupported kind of metamodel hierarchy.");
} else {
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();
@ -252,6 +260,31 @@ public abstract class EClassifierInfo {
return result;
}
/**
* Determine whether the class represented by {@code left} is either the same as
* or is a superclass of the class represented by {@code right} comparing the classifier ID
* and namespace URI.
*/
private boolean isAssignableByID(EClass left, EClass right) {
if (left.getEPackage() != null) {
// Compare namespace URI and classifier Id
if (left.getClassifierID() == right.getClassifierID()
&& right.getEPackage() != null
&& left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI())) {
return true;
}
// Check all supertypes of the right class
for (EClass superClass : right.getEAllSuperTypes()) {
if (left.getClassifierID() == superClass.getClassifierID()
&& superClass.getEPackage() != null
&& left.getEPackage().getNsURI().equals(superClass.getEPackage().getNsURI())) {
return true;
}
}
}
return false;
}
public boolean isFeatureSemanticallyEqualApartFromType(EStructuralFeature f1, EStructuralFeature f2) {
boolean result = f1.getName().equals(f2.getName());
result &= f1.isMany() == f2.isMany();