mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 16:58:56 +00:00
Next patch from Heiko
See https://bugs.eclipse.org/bugs/show_bug.cgi?id=247406
This commit is contained in:
parent
9e5d55916c
commit
54857e60be
4 changed files with 246 additions and 82 deletions
|
@ -8,9 +8,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource.metamodel;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.eclipse.emf.ecore.EAttribute;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*******************************************************************************
|
||||
* 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 java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.xtext.AbstractElement;
|
||||
import org.eclipse.xtext.AbstractRule;
|
||||
import org.eclipse.xtext.Assignment;
|
||||
import org.eclipse.xtext.GrammarUtil;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
|
||||
/**
|
||||
* @author Heiko Behrens - Initial contribution and API
|
||||
*
|
||||
*/
|
||||
public class Xtext2ECoreInterpretationContext {
|
||||
private EClassifierInfos eClassifierInfos;
|
||||
|
||||
Set<EClassifierInfo> currentTypes = new HashSet<EClassifierInfo>();
|
||||
boolean isRuleCallAllowed = true;
|
||||
|
||||
private Xtext2ECoreInterpretationContext(EClassifierInfos classifierInfos) {
|
||||
super();
|
||||
this.eClassifierInfos = classifierInfos;
|
||||
}
|
||||
|
||||
public Xtext2ECoreInterpretationContext(EClassifierInfos eClassifierInfos, EClassifierInfo currentType) {
|
||||
this(eClassifierInfos);
|
||||
currentTypes.add(currentType);
|
||||
}
|
||||
|
||||
private Xtext2ECoreInterpretationContext(Collection<EClassifierInfo> currentTypes,
|
||||
EClassifierInfos classifierInfos, boolean isRuleCallAllowed) {
|
||||
this(classifierInfos);
|
||||
this.currentTypes.addAll(currentTypes);
|
||||
this.isRuleCallAllowed = isRuleCallAllowed;
|
||||
}
|
||||
|
||||
public Xtext2ECoreInterpretationContext(EClassifierInfo newType, EClassifierInfos classifierInfos,
|
||||
boolean isRuleCallAllowed2) {
|
||||
this(classifierInfos);
|
||||
this.currentTypes.add(newType);
|
||||
}
|
||||
|
||||
public void addFeature(Assignment assignment) throws TransformationException {
|
||||
String featureName = assignment.getFeature();
|
||||
boolean isMultivalue = GrammarUtil.isMultipleAssignment(assignment);
|
||||
EClassifierInfo featureTypeInfo;
|
||||
|
||||
if (GrammarUtil.isBooleanAssignment(assignment)) {
|
||||
featureTypeInfo = getEClassifierInfoOrThrowException("ecore::EBoolean", assignment);
|
||||
isMultivalue = false;
|
||||
}
|
||||
else {
|
||||
RuleCall featureRuleCall = (RuleCall) assignment.getTerminal();
|
||||
AbstractRule featureTypeRule = GrammarUtil.calledRule(featureRuleCall);
|
||||
String featureTypeName = GrammarUtil.getReturnTypeName(featureTypeRule);
|
||||
featureTypeInfo = getEClassifierInfoOrThrowException(featureTypeName, assignment);
|
||||
|
||||
}
|
||||
|
||||
for (EClassifierInfo type : currentTypes)
|
||||
type.addFeature(featureName, featureTypeInfo, isMultivalue);
|
||||
}
|
||||
|
||||
private EClassifierInfo getEClassifierInfoOrThrowException(String typeName, AbstractElement parserElement)
|
||||
throws TransformationException {
|
||||
EClassifierInfo featureTypeInfo = eClassifierInfos.getInfo(typeName);
|
||||
if (featureTypeInfo == null) {
|
||||
throw new TransformationException("Cannot resolve type " + typeName, parserElement);
|
||||
}
|
||||
return featureTypeInfo;
|
||||
}
|
||||
|
||||
public Xtext2ECoreInterpretationContext spawnContextForGroup() {
|
||||
Xtext2ECoreInterpretationContext result = new Xtext2ECoreInterpretationContext(currentTypes, eClassifierInfos,
|
||||
isRuleCallAllowed);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Xtext2ECoreInterpretationContext spawnContextWith(EClassifierInfo newType) {
|
||||
if (!isRuleCallAllowed)
|
||||
throw new IllegalStateException("Cannot change type twice within a rule");
|
||||
|
||||
Xtext2ECoreInterpretationContext result = new Xtext2ECoreInterpretationContext(newType, eClassifierInfos,
|
||||
isRuleCallAllowed);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Xtext2ECoreInterpretationContext mergeSpawnedContexts(List<Xtext2ECoreInterpretationContext> contexts) {
|
||||
Xtext2ECoreInterpretationContext result = new Xtext2ECoreInterpretationContext(eClassifierInfos);
|
||||
// result's current types is union of all groups' types
|
||||
// result's isRuleCallAllowed is false if any group's value is false
|
||||
for (Xtext2ECoreInterpretationContext context : contexts) {
|
||||
result.currentTypes.addAll(context.currentTypes);
|
||||
result.isRuleCallAllowed &= context.isRuleCallAllowed;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.eclipse.emf.ecore.EAttribute;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
import org.eclipse.emf.ecore.EClassifier;
|
||||
import org.eclipse.emf.ecore.EDataType;
|
||||
|
@ -31,7 +30,6 @@ import org.eclipse.xtext.GeneratedMetamodel;
|
|||
import org.eclipse.xtext.Grammar;
|
||||
import org.eclipse.xtext.GrammarUtil;
|
||||
import org.eclipse.xtext.Group;
|
||||
import org.eclipse.xtext.LexerRule;
|
||||
import org.eclipse.xtext.ParserRule;
|
||||
import org.eclipse.xtext.ReferencedMetamodel;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
|
@ -69,6 +67,8 @@ public class Xtext2EcoreTransformer {
|
|||
// create types:
|
||||
// iterate rules
|
||||
// - typeref in actions
|
||||
// type hierarchy
|
||||
// - actions
|
||||
for (AbstractRule rule : grammar.getRules()) {
|
||||
// - return types (lexer and parser rules)
|
||||
try {
|
||||
|
@ -85,9 +85,7 @@ public class Xtext2EcoreTransformer {
|
|||
|
||||
// create features
|
||||
// iterate rules
|
||||
// - assignments
|
||||
// - feature in actions
|
||||
// multiplicity!
|
||||
for (AbstractRule rule : grammar.getRules()) {
|
||||
try {
|
||||
if (rule instanceof ParserRule) {
|
||||
|
@ -99,10 +97,6 @@ public class Xtext2EcoreTransformer {
|
|||
}
|
||||
}
|
||||
|
||||
// type hierarchy
|
||||
// - rule calls (optionality)
|
||||
// - actions
|
||||
|
||||
// feature normalization
|
||||
// - uplift of common feature to supertype
|
||||
// - removal in subtype if already in supertype
|
||||
|
@ -118,28 +112,42 @@ public class Xtext2EcoreTransformer {
|
|||
this.getEClassifierInfos().addAll(transformer.getEClassifierInfos());
|
||||
}
|
||||
|
||||
private InterpretationContext deriveFeatures(InterpretationContext context, AbstractElement element)
|
||||
throws TransformationException {
|
||||
private Xtext2ECoreInterpretationContext deriveFeatures(Xtext2ECoreInterpretationContext context,
|
||||
AbstractElement element) throws TransformationException {
|
||||
if (element instanceof Assignment) {
|
||||
Assignment assignment = (Assignment) element;
|
||||
context.addFeature(assignment);
|
||||
}
|
||||
else if (element instanceof Alternatives) {
|
||||
Alternatives alternatives = (Alternatives) element;
|
||||
List<Xtext2ECoreInterpretationContext> contexts = new ArrayList<Xtext2ECoreInterpretationContext>();
|
||||
for (AbstractElement group : alternatives.getGroups()) {
|
||||
contexts.add(deriveFeatures(context, group));
|
||||
}
|
||||
|
||||
if (!GrammarUtil.isOptionalCardinality(alternatives))
|
||||
return context.mergeSpawnedContexts(contexts);
|
||||
}
|
||||
else if (element instanceof Group) {
|
||||
Group group = (Group) element;
|
||||
return deriveFeatures(context, group.getAbstractTokens());
|
||||
return deriveFeatures(context.spawnContextForGroup(), group.getAbstractTokens());
|
||||
}
|
||||
else if (element instanceof RuleCall && !GrammarUtil.isOptionalCardinality(element)) {
|
||||
RuleCall ruleCall = (RuleCall) element;
|
||||
AbstractRule calledRule = GrammarUtil.findRuleForName(grammar, ruleCall.getName());
|
||||
context = context.clone();
|
||||
context.currentType = findOrCreateEClass(calledRule);
|
||||
try {
|
||||
return context.spawnContextWith(findOrCreateEClass(calledRule));
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
throw new TransformationException(e.getMessage(), ruleCall);
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private InterpretationContext deriveFeatures(InterpretationContext context, EList<AbstractElement> elements)
|
||||
throws TransformationException {
|
||||
private Xtext2ECoreInterpretationContext deriveFeatures(Xtext2ECoreInterpretationContext context,
|
||||
EList<AbstractElement> elements) throws TransformationException {
|
||||
for (AbstractElement element : elements) {
|
||||
context = deriveFeatures(context, element);
|
||||
}
|
||||
|
@ -148,8 +156,7 @@ public class Xtext2EcoreTransformer {
|
|||
|
||||
private void deriveFeatures(ParserRule rule) throws TransformationException {
|
||||
EClassifierInfo classInfo = findOrCreateEClass(rule);
|
||||
boolean isGenerated = classInfo.isGenerated();
|
||||
InterpretationContext context = new InterpretationContext(classInfo, isGenerated, true);
|
||||
Xtext2ECoreInterpretationContext context = new Xtext2ECoreInterpretationContext(eClassifierInfos, classInfo);
|
||||
deriveFeatures(context, rule.getAlternatives());
|
||||
}
|
||||
|
||||
|
@ -206,53 +213,6 @@ public class Xtext2EcoreTransformer {
|
|||
calledRuleReturnType.addSupertype(superType);
|
||||
}
|
||||
|
||||
class InterpretationContext {
|
||||
public InterpretationContext(EClassifierInfo currentType, boolean isGeneratedType, boolean isRuleCallAllowed) {
|
||||
super();
|
||||
this.currentType = currentType;
|
||||
this.isGeneratedType = isGeneratedType;
|
||||
this.isRuleCallAllowed = isRuleCallAllowed;
|
||||
}
|
||||
|
||||
public void addFeature(Assignment assignment) throws TransformationException {
|
||||
String featureName = assignment.getFeature();
|
||||
boolean isMultivalue = GrammarUtil.isMultipleAssignment(assignment);
|
||||
EClassifierInfo featureTypeInfo;
|
||||
|
||||
if (GrammarUtil.isBooleanAssignment(assignment)) {
|
||||
featureTypeInfo = getEClassifierInfoOrThrowException("ecore::EBoolean", assignment);
|
||||
isMultivalue = false;
|
||||
}
|
||||
else {
|
||||
RuleCall featureRuleCall = (RuleCall) assignment.getTerminal();
|
||||
AbstractRule featureTypeRule = GrammarUtil.calledRule(featureRuleCall);
|
||||
String featureTypeName = GrammarUtil.getReturnTypeName(featureTypeRule);
|
||||
featureTypeInfo = getEClassifierInfoOrThrowException(featureTypeName, assignment);
|
||||
|
||||
}
|
||||
|
||||
currentType.addFeature(featureName, featureTypeInfo, isMultivalue);
|
||||
}
|
||||
|
||||
private EClassifierInfo getEClassifierInfoOrThrowException(String typeName, AbstractElement parserElement)
|
||||
throws TransformationException {
|
||||
EClassifierInfo featureTypeInfo = eClassifierInfos.getInfo(typeName);
|
||||
if (featureTypeInfo == null) {
|
||||
throw new TransformationException("Cannot resolve type " + typeName, parserElement);
|
||||
}
|
||||
return featureTypeInfo;
|
||||
}
|
||||
|
||||
public InterpretationContext clone() {
|
||||
return new InterpretationContext(currentType, isGeneratedType, isRuleCallAllowed);
|
||||
}
|
||||
|
||||
// TODO : Use set of types to reflect mandatory actions
|
||||
EClassifierInfo currentType;
|
||||
boolean isGeneratedType;
|
||||
boolean isRuleCallAllowed = true;
|
||||
}
|
||||
|
||||
private void collectEPackages() {
|
||||
EList<AbstractMetamodelDeclaration> metamodelDeclarations = grammar.getMetamodelDeclarations();
|
||||
for (AbstractMetamodelDeclaration metamodelDeclaration : metamodelDeclarations) {
|
||||
|
|
|
@ -33,8 +33,7 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
with(XtextStandaloneSetup.class);
|
||||
}
|
||||
|
||||
private EPackage getEPackageFromGrammar(String xtextGrammar)
|
||||
throws Exception {
|
||||
private EPackage getEPackageFromGrammar(String xtextGrammar) throws Exception {
|
||||
Grammar grammar = (Grammar) getModel(xtextGrammar);
|
||||
Xtext2EcoreTransformer xtext2EcoreTransformer = new Xtext2EcoreTransformer();
|
||||
List<EPackage> metamodels = xtext2EcoreTransformer.transform(grammar);
|
||||
|
@ -46,22 +45,22 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
return result;
|
||||
}
|
||||
|
||||
private EAttribute assertFeatureConfiguration(EClass eClass, int attributeIndex,
|
||||
String featureName, String featureTypeName) {
|
||||
private EAttribute assertFeatureConfiguration(EClass eClass, int attributeIndex, String featureName,
|
||||
String featureTypeName) {
|
||||
EAttribute feature = eClass.getEAttributes().get(attributeIndex);
|
||||
assertEquals(featureName, feature.getName());
|
||||
assertNotNull(feature.getEType());
|
||||
assertEquals(featureTypeName, feature.getEType().getName());
|
||||
|
||||
|
||||
return feature;
|
||||
}
|
||||
|
||||
private EAttribute assertFeatureConfiguration(EClass eClass, int attributeIndex,
|
||||
String featureName, String featureTypeName, int lowerBound, int upperBound) {
|
||||
|
||||
private EAttribute assertFeatureConfiguration(EClass eClass, int attributeIndex, String featureName,
|
||||
String featureTypeName, int lowerBound, int upperBound) {
|
||||
EAttribute feature = assertFeatureConfiguration(eClass, attributeIndex, featureName, featureTypeName);
|
||||
assertEquals(lowerBound, feature.getLowerBound());
|
||||
assertEquals(upperBound, feature.getUpperBound());
|
||||
|
||||
|
||||
return feature;
|
||||
}
|
||||
|
||||
|
@ -153,7 +152,7 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
assertFeatureConfiguration(ruleA, 1, "featureB", "EInt", 0, -1);
|
||||
}
|
||||
|
||||
public void testFeatureAndInheritanceOptionalRuleCall() throws Exception {
|
||||
public void testFeaturesAndInheritanceOptionalRuleCall() throws Exception {
|
||||
final String grammar = "language test generate test 'http://test' RuleA: RuleB? featureA=INT; RuleB: featureB=STRING;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
assertEquals(2, ePackage.getEClassifiers().size());
|
||||
|
@ -161,15 +160,15 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
assertNotNull(ruleA);
|
||||
EClass ruleB = (EClass) ePackage.getEClassifier("RuleB");
|
||||
assertNotNull(ruleB);
|
||||
|
||||
|
||||
assertEquals(1, ruleA.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleA, 0, "featureA", "EInt");
|
||||
|
||||
|
||||
assertEquals(1, ruleB.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleB, 0, "featureB", "EString");
|
||||
}
|
||||
|
||||
public void testFeatureAndInheritanceMandatoryRuleCall() throws Exception {
|
||||
public void testFeaturesAndInheritanceMandatoryRuleCall() throws Exception {
|
||||
final String grammar = "language test generate test 'http://test' RuleA: RuleB featureA=INT; RuleB: featureB=STRING;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
assertEquals(2, ePackage.getEClassifiers().size());
|
||||
|
@ -177,12 +176,109 @@ public class Xtext2EcoreTransformerTests extends AbstractGeneratorTest {
|
|||
assertNotNull(ruleA);
|
||||
EClass ruleB = (EClass) ePackage.getEClassifier("RuleB");
|
||||
assertNotNull(ruleB);
|
||||
|
||||
|
||||
assertEquals(0, ruleA.getEAttributes().size());
|
||||
|
||||
|
||||
assertEquals(2, ruleB.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleB, 0, "featureA", "EInt");
|
||||
assertFeatureConfiguration(ruleB, 1, "featureB", "EString");
|
||||
}
|
||||
|
||||
public void testFeaturesAndInheritanceOfMandatoryAlternativeRuleCalls() throws Exception {
|
||||
final String grammar = "language test generate test 'http://test' RuleA: (RuleB|RuleC featureC1=ID) featureA=ID; RuleB: featureB=ID; RuleC: featureC2=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);
|
||||
|
||||
// test inheritance
|
||||
assertTrue(ruleA.getESuperTypes().isEmpty());
|
||||
assertEquals(1, ruleB.getESuperTypes().size());
|
||||
assertEquals(ruleA, ruleB.getESuperTypes().get(0));
|
||||
assertEquals(1, ruleC.getESuperTypes().size());
|
||||
assertEquals(ruleA, ruleC.getESuperTypes().get(0));
|
||||
|
||||
// test all features are separated
|
||||
assertEquals(0, ruleA.getEAttributes().size());
|
||||
assertEquals(2, ruleB.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleB, 0, "featureA", "EString");
|
||||
assertFeatureConfiguration(ruleB, 1, "featureB", "EString");
|
||||
assertEquals(3, ruleC.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleC, 0, "featureC1", "EString");
|
||||
assertFeatureConfiguration(ruleC, 1, "featureA", "EString");
|
||||
assertFeatureConfiguration(ruleC, 2, "featureC2", "EString");
|
||||
}
|
||||
|
||||
public void testFeaturesAndInheritanceOfOptionalOptionalRuleCalls() throws Exception {
|
||||
final String grammar = "language test generate test 'http://test' RuleA: (RuleB|RuleC featureC1=ID)? featureA=ID; RuleB: featureB=ID; RuleC: featureC2=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);
|
||||
|
||||
// test inheritance
|
||||
assertTrue(ruleA.getESuperTypes().isEmpty());
|
||||
assertEquals(1, ruleB.getESuperTypes().size());
|
||||
assertEquals(ruleA, ruleB.getESuperTypes().get(0));
|
||||
assertEquals(1, ruleC.getESuperTypes().size());
|
||||
assertEquals(ruleA, ruleC.getESuperTypes().get(0));
|
||||
|
||||
// test all features are separated
|
||||
assertEquals(1, ruleA.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleA, 0, "featureA", "EString");
|
||||
assertEquals(1, ruleB.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleB, 0, "featureB", "EString");
|
||||
assertEquals(2, ruleC.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleC, 0, "featureC1", "EString");
|
||||
assertFeatureConfiguration(ruleC, 1, "featureC2", "EString");
|
||||
}
|
||||
|
||||
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;";
|
||||
EPackage ePackage = getEPackageFromGrammar(grammar);
|
||||
assertEquals(4, 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);
|
||||
EClass ruleD = (EClass) ePackage.getEClassifier("RuleD");
|
||||
assertNotNull(ruleD);
|
||||
|
||||
// test inheritance
|
||||
assertTrue(ruleA.getESuperTypes().isEmpty());
|
||||
assertEquals(1, ruleB.getESuperTypes().size());
|
||||
assertEquals(ruleA, ruleB.getESuperTypes().get(0));
|
||||
assertEquals(1, ruleC.getESuperTypes().size());
|
||||
assertEquals(ruleA, ruleC.getESuperTypes().get(0));
|
||||
assertEquals(1, ruleD.getESuperTypes().size());
|
||||
assertEquals(ruleA, ruleD.getESuperTypes().get(0));
|
||||
|
||||
// test all features are separated
|
||||
assertEquals(2, ruleA.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleA, 0, "featureBC", "EString");
|
||||
assertFeatureConfiguration(ruleA, 1, "featureA", "EString");
|
||||
assertEquals(1, ruleB.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleB, 0, "featureB2", "EString");
|
||||
assertEquals(4, ruleC.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleC, 0, "featureC1", "EString");
|
||||
assertFeatureConfiguration(ruleC, 1, "featureCD", "EString");
|
||||
assertFeatureConfiguration(ruleC, 2, "featureA", "EString");
|
||||
assertFeatureConfiguration(ruleC, 3, "featureC2", "EString");
|
||||
assertEquals(4, ruleD.getEAttributes().size());
|
||||
assertFeatureConfiguration(ruleD, 0, "featureD1", "EString");
|
||||
assertFeatureConfiguration(ruleD, 1, "featureCD", "EString");
|
||||
assertFeatureConfiguration(ruleD, 2, "featureA", "EString");
|
||||
assertFeatureConfiguration(ruleD, 3, "featureD2", "EString");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue