mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 16:58:56 +00:00
Applied patch from Heiko:
Feature uplift see https://bugs.eclipse.org/bugs/attachment.cgi?id=113868
This commit is contained in:
parent
2e8c98c55c
commit
c7ac0b4446
2 changed files with 179 additions and 57 deletions
|
@ -1,3 +1,11 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource.metamodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
@ -5,19 +13,24 @@ import junit.framework.TestCase;
|
|||
import org.eclipse.emf.ecore.EAttribute;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
import org.eclipse.emf.ecore.EDataType;
|
||||
import org.eclipse.emf.ecore.EReference;
|
||||
import org.eclipse.emf.ecore.EcoreFactory;
|
||||
import org.eclipse.xtext.resource.metamodel.EClassifierInfo.EClassInfo;
|
||||
|
||||
/**
|
||||
* @author Heiko Behrens - Initial contribution and API
|
||||
*
|
||||
*/
|
||||
public class TypeHierarchyHelperTests extends TestCase {
|
||||
|
||||
private TypeHierarchyHelper helper;
|
||||
private EClassifierInfos infos = new EClassifierInfos();
|
||||
private EDataType INT = EcoreFactory.eINSTANCE.createEDataType();
|
||||
// private EDataType STRING = EcoreFactory.eINSTANCE.createEDataType();
|
||||
private EDataType STRING = EcoreFactory.eINSTANCE.createEDataType();
|
||||
|
||||
private void liftUpFeatures() throws Exception {
|
||||
helper = new TypeHierarchyHelper(infos);
|
||||
helper.liftUpFeatures();
|
||||
helper.liftUpFeaturesRecursively();
|
||||
}
|
||||
|
||||
private EClassInfo addClass(String name, boolean isGenerated) {
|
||||
|
@ -31,7 +44,7 @@ public class TypeHierarchyHelperTests extends TestCase {
|
|||
private EClassInfo addClass(String name) {
|
||||
return addClass(name, true);
|
||||
}
|
||||
|
||||
|
||||
private void addAttribute(EClassInfo eClass, EDataType eType, String name) {
|
||||
EAttribute feature = EcoreFactory.eINSTANCE.createEAttribute();
|
||||
feature.setName(name);
|
||||
|
@ -39,6 +52,13 @@ public class TypeHierarchyHelperTests extends TestCase {
|
|||
eClass.getEClass().getEStructuralFeatures().add(feature);
|
||||
}
|
||||
|
||||
private void addReference(EClassInfo eClass, EClassInfo ref, String name) {
|
||||
EReference feature = EcoreFactory.eINSTANCE.createEReference();
|
||||
feature.setName(name);
|
||||
feature.setEType(ref.getEClassifier());
|
||||
eClass.getEClass().getEStructuralFeatures().add(feature);
|
||||
}
|
||||
|
||||
public void testSimpeCase01() throws Exception {
|
||||
EClassInfo a = addClass("a");
|
||||
EClassInfo b = addClass("b");
|
||||
|
@ -51,9 +71,9 @@ public class TypeHierarchyHelperTests extends TestCase {
|
|||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, c.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
|
||||
liftUpFeatures();
|
||||
|
||||
|
||||
assertEquals(1, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, c.getEClass().getEStructuralFeatures().size());
|
||||
|
@ -68,13 +88,13 @@ public class TypeHierarchyHelperTests extends TestCase {
|
|||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
|
||||
liftUpFeatures();
|
||||
|
||||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
}
|
||||
|
||||
|
||||
public void testRecursiveUplift01() throws Exception {
|
||||
// no uplift for less than two children
|
||||
EClassInfo a = addClass("a");
|
||||
|
@ -86,26 +106,26 @@ public class TypeHierarchyHelperTests extends TestCase {
|
|||
c.addSupertype(a);
|
||||
d.addSupertype(c);
|
||||
e.addSupertype(c);
|
||||
|
||||
|
||||
addAttribute(b, INT, "f1");
|
||||
addAttribute(d, INT, "f1");
|
||||
addAttribute(e, INT, "f1");
|
||||
|
||||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, c.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, d.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, e.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
|
||||
liftUpFeatures();
|
||||
|
||||
|
||||
assertEquals(1, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, c.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, d.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, e.getEClass().getEStructuralFeatures().size());
|
||||
}
|
||||
|
||||
|
||||
public void testNikolaus() throws Exception {
|
||||
// no uplift for less than two children
|
||||
EClassInfo a = addClass("a");
|
||||
|
@ -119,24 +139,87 @@ public class TypeHierarchyHelperTests extends TestCase {
|
|||
d.addSupertype(c);
|
||||
e.addSupertype(b);
|
||||
e.addSupertype(c);
|
||||
|
||||
|
||||
addAttribute(b, STRING, "f2");
|
||||
addAttribute(c, STRING, "f2");
|
||||
addAttribute(d, INT, "f1");
|
||||
addAttribute(e, INT, "f1");
|
||||
|
||||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, c.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, c.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, d.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, e.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
|
||||
liftUpFeatures();
|
||||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
assertEquals(1, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, c.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, d.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, e.getEClass().getEStructuralFeatures().size());
|
||||
}
|
||||
|
||||
public void testImcompatipleFeatures() throws Exception {
|
||||
EClassInfo a = addClass("a");
|
||||
EClassInfo b = addClass("b");
|
||||
EClassInfo c = addClass("c");
|
||||
b.addSupertype(a);
|
||||
c.addSupertype(a);
|
||||
addAttribute(b, INT, "f1");
|
||||
addAttribute(c, STRING, "f1");
|
||||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, c.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
liftUpFeatures();
|
||||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, c.getEClass().getEStructuralFeatures().size());
|
||||
}
|
||||
|
||||
public void testReferences() throws Exception {
|
||||
EClassInfo a = addClass("a");
|
||||
EClassInfo b = addClass("b");
|
||||
EClassInfo c = addClass("c");
|
||||
EClassInfo d = addClass("d");
|
||||
b.addSupertype(a);
|
||||
c.addSupertype(a);
|
||||
addReference(b, d, "r1");
|
||||
addReference(c, d, "r1");
|
||||
|
||||
assertEquals(0, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, c.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
liftUpFeatures();
|
||||
|
||||
assertEquals(1, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, c.getEClass().getEStructuralFeatures().size());
|
||||
}
|
||||
|
||||
public void testDublicateDerivedFeature() throws Exception {
|
||||
EClassInfo a = addClass("a");
|
||||
EClassInfo b = addClass("b");
|
||||
EClassInfo c = addClass("b");
|
||||
b.addSupertype(a);
|
||||
c.addSupertype(b);
|
||||
addAttribute(a, INT, "f");
|
||||
addAttribute(c, INT, "f");
|
||||
|
||||
assertEquals(1, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(1, c.getEClass().getEStructuralFeatures().size());
|
||||
|
||||
helper = new TypeHierarchyHelper(infos);
|
||||
helper.removeDuplicateDerivedFeatures();
|
||||
|
||||
assertEquals(1, a.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, b.getEClass().getEStructuralFeatures().size());
|
||||
assertEquals(0, c.getEClass().getEStructuralFeatures().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -234,14 +234,13 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
assertEquals(ruleA, ruleC.getESuperTypes().get(0));
|
||||
|
||||
// test all features are separated
|
||||
assertEquals(0, ruleA.getEAttributes().size());
|
||||
assertEquals(2, ruleB.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleB, 0, "featureA", "EString");
|
||||
assertAttributeConfiguration(ruleB, 1, "featureB", "EString");
|
||||
assertEquals(3, ruleC.getEAttributes().size());
|
||||
assertEquals(1, ruleA.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleA, 0, "featureA", "EString");
|
||||
assertEquals(1, ruleB.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleB, 0, "featureB", "EString");
|
||||
assertEquals(2, ruleC.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleC, 0, "featureC1", "EString");
|
||||
assertAttributeConfiguration(ruleC, 1, "featureA", "EString");
|
||||
assertAttributeConfiguration(ruleC, 2, "featureC2", "EString");
|
||||
assertAttributeConfiguration(ruleC, 1, "featureC2", "EString");
|
||||
}
|
||||
|
||||
public void testFeaturesAndInheritanceOfOptionalOptionalRuleCalls() throws Exception {
|
||||
|
@ -273,7 +272,11 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
}
|
||||
|
||||
public void testFeaturesAndInheritanceOfNestedRuleCalls() throws Exception {
|
||||
final String grammar = "language test generate test 'http://test' RuleA: ((RuleB|RuleC featureC1=ID)? featureBC=ID | (RuleC|RuleD featureD1=ID) featureCD=ID) featureA=ID; RuleB: featureB2=ID; RuleC: featureC2=ID; RuleD: featureD2=ID;";
|
||||
String grammar = "language test generate test 'http://test'";
|
||||
grammar += " RuleA: ((RuleB|RuleC featureC1=ID)? featureBC=ID | (RuleC|RuleD featureD1=ID) featureCD=ID) featureA=ID;";
|
||||
grammar += " RuleB: featureB2=ID;";
|
||||
grammar += " RuleC: featureC2=ID;";
|
||||
grammar += " RuleD: featureD2=ID;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
assertEquals(4, ePackage.getEClassifiers().size());
|
||||
EClass ruleA = (EClass) ePackage.getEClassifier("RuleA");
|
||||
|
@ -300,16 +303,14 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
assertAttributeConfiguration(ruleA, 1, "featureA", "EString");
|
||||
assertEquals(1, ruleB.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleB, 0, "featureB2", "EString");
|
||||
assertEquals(4, ruleC.getEAttributes().size());
|
||||
assertEquals(3, ruleC.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleC, 0, "featureC1", "EString");
|
||||
assertAttributeConfiguration(ruleC, 1, "featureCD", "EString");
|
||||
assertAttributeConfiguration(ruleC, 2, "featureA", "EString");
|
||||
assertAttributeConfiguration(ruleC, 3, "featureC2", "EString");
|
||||
assertEquals(4, ruleD.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleC, 2, "featureC2", "EString");
|
||||
assertEquals(3, ruleD.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleD, 0, "featureD1", "EString");
|
||||
assertAttributeConfiguration(ruleD, 1, "featureCD", "EString");
|
||||
assertAttributeConfiguration(ruleD, 2, "featureA", "EString");
|
||||
assertAttributeConfiguration(ruleD, 3, "featureD2", "EString");
|
||||
assertAttributeConfiguration(ruleD, 2, "featureD2", "EString");
|
||||
}
|
||||
|
||||
public void testFeaturesAndInheritanceOfActions01() throws Exception {
|
||||
|
@ -331,15 +332,16 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
assertEquals(ruleA, sub.getESuperTypes().get(0));
|
||||
|
||||
// test features
|
||||
assertEquals(0, ruleA.getEAttributes().size());
|
||||
assertEquals(1, add.getEAttributes().size());
|
||||
assertAttributeConfiguration(add, 0, "featureAS", "EString");
|
||||
assertEquals(1, add.getEReferences().size());
|
||||
assertReferenceConfiguration(add, 0, "a", "RuleA", true, 0, 1);
|
||||
assertEquals(1, sub.getEAttributes().size());
|
||||
assertAttributeConfiguration(sub, 0, "featureAS", "EString");
|
||||
assertEquals(1, sub.getEReferences().size());
|
||||
assertReferenceConfiguration(sub, 0, "a", "RuleA", true, 0, 1);
|
||||
assertEquals(1, ruleA.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleA, 0, "featureAS", "EString");
|
||||
assertEquals(1, ruleA.getEReferences().size());
|
||||
assertReferenceConfiguration(ruleA, 0, "a", "RuleA", false, 0, 1);
|
||||
|
||||
assertEquals(0, add.getEAttributes().size());
|
||||
assertEquals(0, add.getEReferences().size());
|
||||
|
||||
assertEquals(0, sub.getEAttributes().size());
|
||||
assertEquals(0, sub.getEReferences().size());
|
||||
}
|
||||
|
||||
public void testFeaturesAndInheritanceOfActions02() throws Exception {
|
||||
|
@ -421,7 +423,7 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
grammar += " RuleC: featureC=ID;";
|
||||
grammar += " RuleD returns TypeB: featureD=ID;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
|
||||
|
||||
assertEquals(3, ePackage.getEClassifiers().size());
|
||||
EClass ruleA = (EClass) ePackage.getEClassifier("RuleA");
|
||||
assertNotNull(ruleA);
|
||||
|
@ -495,14 +497,13 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
grammar += " generate t2 'http://t2' as target";
|
||||
grammar += " RuleA: featureA=ID;"; // no alias => cannot be created
|
||||
grammar += " RuleB returns target::TypeB: featureB=ID;";
|
||||
|
||||
|
||||
errorAcceptorMock.acceptError(same(ErrorCode.AliasForMetamodelAlreadyExists), (String) anyObject(),
|
||||
(EObject) anyObject());
|
||||
errorAcceptorMock.acceptError(same(ErrorCode.CannotCreateTypeInSealedMetamodel), (String) anyObject(),
|
||||
(EObject) anyObject());
|
||||
errorAcceptorMock.acceptError(same(ErrorCode.NoSuchTypeAvailable), (String) anyObject(),
|
||||
(EObject) anyObject());
|
||||
|
||||
errorAcceptorMock.acceptError(same(ErrorCode.NoSuchTypeAvailable), (String) anyObject(), (EObject) anyObject());
|
||||
|
||||
List<EPackage> ePackages = getEPackagesFromGrammar(grammar);
|
||||
assertEquals(1, ePackages.size());
|
||||
EPackage t1 = ePackages.get(0);
|
||||
|
@ -557,12 +558,10 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
}
|
||||
|
||||
public void testAddingDifferentFeaturesWithSameName01() throws Exception {
|
||||
// simple datatypes do not have a common compatible type
|
||||
final String grammar = "" +
|
||||
" language test generate test 'http://test'" +
|
||||
" RuleA returns TypeA: featureA=ID;" +
|
||||
" RuleB returns TypeA: featureA=INT;";
|
||||
|
||||
// simple datatypes do not have a common compatible type
|
||||
final String grammar = "" + " language test generate test 'http://test'" + " RuleA returns TypeA: featureA=ID;"
|
||||
+ " RuleB returns TypeA: featureA=INT;";
|
||||
|
||||
errorAcceptorMock.acceptError(same(ErrorCode.NoCompatibleFeatureTypeAvailable), (String) anyObject(),
|
||||
(EObject) anyObject());
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
|
@ -581,7 +580,7 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
grammar += " RuleC: RuleD;";
|
||||
grammar += " RuleD: featureD=ID;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
|
||||
|
||||
assertEquals(3, ePackage.getEClassifiers().size());
|
||||
EClass typeA = (EClass) ePackage.getEClassifier("TypeA");
|
||||
assertNotNull(typeA);
|
||||
|
@ -602,7 +601,7 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
grammar += " RuleC: featureC=INT;";
|
||||
grammar += " RuleD: featureD=ID;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
|
||||
|
||||
assertEquals(3, ePackage.getEClassifiers().size());
|
||||
EClass typeA = (EClass) ePackage.getEClassifier("TypeA");
|
||||
assertNotNull(typeA);
|
||||
|
@ -614,9 +613,49 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
assertEquals(2, typeA.getEAllAttributes().size());
|
||||
assertAttributeConfiguration(typeA, 0, "featureA1", "EString");
|
||||
assertAttributeConfiguration(typeA, 1, "featureA4", "EInt");
|
||||
|
||||
|
||||
assertEquals(2, typeA.getEReferences().size());
|
||||
assertReferenceConfiguration(typeA, 0, "featureA2", "EObject", true, 0, 1);
|
||||
assertReferenceConfiguration(typeA, 1, "featureA3", "RuleC", true, 0, 1);
|
||||
}
|
||||
|
||||
public void testUplift01() throws Exception {
|
||||
String grammar = "language test generate test 'http://test'";
|
||||
grammar += " RuleA: (RuleB|RuleC) featureA=ID;";
|
||||
grammar += " RuleB: featureB=INT;";
|
||||
grammar += " RuleC: (featureA=ID)?;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
|
||||
assertEquals(3, ePackage.getEClassifiers().size());
|
||||
EClass ruleA = (EClass) ePackage.getEClassifier("RuleA");
|
||||
assertNotNull(ruleA);
|
||||
EClass ruleB = (EClass) ePackage.getEClassifier("RuleB");
|
||||
assertNotNull(ruleB);
|
||||
EClass ruleC = (EClass) ePackage.getEClassifier("RuleC");
|
||||
assertNotNull(ruleC);
|
||||
|
||||
assertEquals(1, ruleA.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleA, 0, "featureA", "EString");
|
||||
|
||||
assertEquals(1, ruleB.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleB, 0, "featureB", "EInt");
|
||||
|
||||
assertEquals(0, ruleC.getEAttributes().size());
|
||||
}
|
||||
|
||||
public void testCallOfUndeclaredRule() throws Exception {
|
||||
String grammar = "language test generate test 'http://test'";
|
||||
grammar += " RuleA: CallOfUndeclaredRule featureA=ID;";
|
||||
|
||||
errorAcceptorMock.acceptError(same(ErrorCode.NoSuchRuleAvailable), (String) anyObject(),
|
||||
(EObject) anyObject());
|
||||
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
assertEquals(1, ePackage.getEClassifiers().size());
|
||||
EClass ruleA = (EClass) ePackage.getEClassifier("RuleA");
|
||||
assertNotNull(ruleA);
|
||||
assertEquals(1, ruleA.getEAttributes().size());
|
||||
assertAttributeConfiguration(ruleA, 0, "featureA", "EString");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue