[xtext][ecoreInference] Fix: Wrong error on compatible features in grammar editor

This commit is contained in:
Sebastian Zarnekow 2011-11-10 20:03:12 +01:00
parent 1add44adfb
commit d34390a611
3 changed files with 78 additions and 15 deletions

View file

@ -32,6 +32,7 @@ import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
@ -307,18 +308,12 @@ public class EcoreUtil2 extends EcoreUtil {
}
public static EClassifier getCompatibleType(EClassifier typeA, EClassifier typeB) {
if (typeA.equals(typeB))
return typeA;
// no common type for simple datatypes available
if (!(typeA instanceof EClass && typeB instanceof EClass))
return null;
List<EClass> sortedCandidates = getSortedCommonCompatibleTypeCandidates((EClass) typeA, (EClass) typeB);
for (EClass candidate : sortedCandidates)
if (isCommonCompatibleType(candidate, sortedCandidates))
return candidate;
return EcorePackage.Literals.EOBJECT;
EClassifier result = getCompatibleType(typeA, typeB, null);
if (result != null)
return result;
if (typeA instanceof EClass && typeB instanceof EClass)
return EcorePackage.Literals.EOBJECT;
return null;
}
/**
@ -327,6 +322,17 @@ public class EcoreUtil2 extends EcoreUtil {
public static EClassifier getCompatibleType(EClassifier typeA, EClassifier typeB, EObject grammarContext) {
if (typeA.equals(typeB))
return typeA;
if (typeA instanceof EDataType && typeB instanceof EDataType) {
Class<?> instanceClassA = typeA.getInstanceClass();
Class<?> instanceClassB = typeB.getInstanceClass();
if (instanceClassA != null && instanceClassB != null) {
if (instanceClassA.isAssignableFrom(instanceClassB))
return typeA;
if (instanceClassB.isAssignableFrom(instanceClassA))
return typeB;
}
}
// no common type for simple datatypes available
if (!(typeA instanceof EClass && typeB instanceof EClass))
return null;

View file

@ -258,8 +258,9 @@ public abstract class EClassifierInfo {
result &= f1Type.isSuperTypeOf(f2Type);
result &= ((EReference) f1).isContainment() == ((EReference) f2).isContainment();
result &= ((EReference) f1).isContainer() == ((EReference) f2).isContainer();
} else
result &= f1.getEType().equals(f2.getEType());
} else {
result &= f1.getEType().equals(EcoreUtil2.getCompatibleType(f1.getEType(), f2.getEType()));
}
return result;
}
@ -337,7 +338,7 @@ public abstract class EClassifierInfo {
EClassifier compatibleType = EcoreUtil2.getCompatibleType(existingFeature.getEType(), newFeature.getEType(), grammarElement);
if (compatibleType == null)
throw new TransformationException(TransformationErrorCode.NoCompatibleFeatureTypeAvailable,
"Cannot find compatible type for features", grammarElement);
"Cannot find compatible type for the feature '" + existingFeature.getName() + "'", grammarElement);
if (isGenerated(existingFeature)) {
existingFeature.setEType(compatibleType);

View file

@ -14,6 +14,7 @@ import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EPackage.Registry;
@ -43,6 +44,13 @@ public class EcoreUtil2Test extends AbstractXtextTests {
return result;
}
private EDataType createEDataType(String name, Class<?> instanceClass) {
EDataType result = EcoreFactory.eINSTANCE.createEDataType();
result.setName(name);
result.setInstanceClass(instanceClass);
return result;
}
public void testSimple() throws Exception {
ResourceSet rs = new ResourceSetImpl();
Resource foo = rs.createResource(URI.createURI("foo.xmi"), ContentHandler.UNSPECIFIED_CONTENT_TYPE);
@ -144,6 +152,54 @@ public class EcoreUtil2Test extends AbstractXtextTests {
assertSame(a, EcoreUtil2.getCompatibleType(d, e));
}
public void testGetCompatibleType_01() {
EDataType aString = createEDataType("a", String.class);
EDataType anotherString = createEDataType("b", String.class);
assertSame(aString, EcoreUtil2.getCompatibleType(aString, anotherString, null));
assertSame(anotherString, EcoreUtil2.getCompatibleType(anotherString, aString, null));
}
public void testGetCompatibleType_02() {
EDataType aString = createEDataType("a", String.class);
EDataType anObject = createEDataType("b", Object.class);
assertSame(anObject, EcoreUtil2.getCompatibleType(aString, anObject, null));
assertSame(anObject, EcoreUtil2.getCompatibleType(anObject, aString, null));
}
public void testGetCompatibleType_03() {
EDataType aCharSequence = createEDataType("a", CharSequence.class);
EDataType anAppendable = createEDataType("b", Appendable.class);
assertSame(null, EcoreUtil2.getCompatibleType(aCharSequence, anAppendable, null));
assertSame(null, EcoreUtil2.getCompatibleType(anAppendable, aCharSequence, null));
}
public void testGetCompatibleType_04() {
EDataType aString = createEDataType("a", String.class);
EDataType anotherString = createEDataType("b", String.class);
assertSame(aString, EcoreUtil2.getCompatibleType(aString, anotherString));
assertSame(anotherString, EcoreUtil2.getCompatibleType(anotherString, aString));
}
public void testGetCompatibleType_05() {
EDataType aString = createEDataType("a", String.class);
EDataType anObject = createEDataType("b", Object.class);
assertSame(anObject, EcoreUtil2.getCompatibleType(aString, anObject));
assertSame(anObject, EcoreUtil2.getCompatibleType(anObject, aString));
}
public void testGetCompatibleType_06() {
EDataType aCharSequence = createEDataType("a", CharSequence.class);
EDataType anAppendable = createEDataType("b", Appendable.class);
assertSame(null, EcoreUtil2.getCompatibleType(aCharSequence, anAppendable));
assertSame(null, EcoreUtil2.getCompatibleType(anAppendable, aCharSequence));
}
public void testGetAllSuperTypesWithCycle() {
EClass a = createEClass("a");
EClass b = createEClass("b");