parsetree reconstructor refactoring (part 1)

This commit is contained in:
sefftinge 2008-07-04 13:49:07 +00:00 committed by sefftinge
parent 6b9615f578
commit db307dea71
5 changed files with 122 additions and 102 deletions

View file

@ -10,8 +10,6 @@
package org.eclipse.xtext;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.parsetree.NodeUtil;
import org.eclipse.xtext.parsetree.XtextGrammarTestParseTreeConstructor;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
/**
@ -32,12 +30,4 @@ public class XtextGrammarTest extends AbstractGeneratorTest {
assertWithXtend("'name'","parserRules.first().alternatives.feature",grammar);
}
public void testSerialization() throws Exception {
String model = "generate foo 'bar' Foo : ( 'stuff' '{' '}' STRING ) ? ;";
EObject grammar = (EObject) getModel(model);
XtextGrammarTestParseTreeConstructor ptc = (XtextGrammarTestParseTreeConstructor) getParseTreeConstructor();
ptc.update(grammar);
assertEquals(model, NodeUtil.getNodeAdapter(grammar).getParserNode().serialize());
}
}

View file

@ -9,9 +9,9 @@
package org.eclipse.xtext.parsetree.reconstr;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.parsetree.IParseTreeConstructor;
import org.eclipse.xtext.parsetree.NodeUtil;
import org.eclipse.xtext.parsetree.reconstr.callbacks.SimpleSerializingCallback;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
import org.eclipse.xtext.xtext2ecore.EcoreModelComparator;
public class ComplexReconstrTest extends AbstractGeneratorTest {
@ -34,16 +34,21 @@ public class ComplexReconstrTest extends AbstractGeneratorTest {
private String parseAndSerialize(String model) throws Exception {
EObject result = (EObject) getModel(model);
IParseTreeConstructor con = getParseTreeConstructor();
con.update(result);
String resultString = NodeUtil.getRootNode(result).serialize();
return resultString;
SimpleSerializingCallback callback = new SimpleSerializingCallback(getValueConverterService());
con.update(result,callback);
return callback.toString();
}
public void testNormalizableCompositeNodesIncluded() throws Exception {
reconstructAndCompare("a");
reconstructAndCompare("a + b");
}
private void reconstructAndCompare(String mymodel) throws Exception, InterruptedException {
EObject model = getModel(mymodel);
EObject model2 = getModel(parseAndSerialize(mymodel));
EcoreModelComparator ecoreModelComparator = new EcoreModelComparator();
assertFalse(ecoreModelComparator.modelsDiffer(model, model2));
}
// public void testNormalizableCompositeNodesIncluded() throws Exception {
// EObject model = getModel("a");
// IParseTreeConstructor con = getParseTreeConstructor();
// con.update(model);
// CompositeNode node = NodeUtil.getRootNode(model);
// assertEquals("Op",((RuleCall)node.getGrammarElement()).getName());
// }
}

View file

@ -9,8 +9,7 @@
package org.eclipse.xtext.parsetree.reconstr;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.parsetree.IParseTreeConstructor;
import org.eclipse.xtext.parsetree.NodeUtil;
import org.eclipse.xtext.parsetree.reconstr.callbacks.SimpleSerializingCallback;
import org.eclipse.xtext.testlanguages.SimpleExpressionsStandaloneSetup;
import org.eclipse.xtext.tests.AbstractGeneratorTest;
@ -31,19 +30,15 @@ public class SimpleReconstrTest extends AbstractGeneratorTest {
private String parseAndSerialize(String model) throws Exception {
EObject result = (EObject) getModel(model);
IParseTreeConstructor con = getParseTreeConstructor();
con.update(result);
String resultString = NodeUtil.getRootNode(result).serialize();
return resultString;
SimpleSerializingCallback callback = new SimpleSerializingCallback(getValueConverterService());
con.update(result, callback);
return callback.toString();
}
public void testSimpleExpressions() throws Exception {
with(SimpleExpressionsStandaloneSetup.class);
String model = "a + b - c * d / e";
EObject result = (EObject) getModel(model);
IParseTreeConstructor con = getParseTreeConstructor();
con.update(result);
String resultString = NodeUtil.getRootNode(result).serialize();
assertEquals(model,resultString);
assertEquals(model,parseAndSerialize(model));
}
@Override

View file

@ -22,10 +22,11 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.m2t.type.emf.EmfRegistryMetaModel;
import org.eclipse.xtext.GenerateAllTestGrammars;
import org.eclipse.xtext.XtextStandaloneSetup;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.parser.IAstFactory;
import org.eclipse.xtext.parser.IParser;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.parsetree.IParseTreeConstructor;
import org.eclipse.xtext.parsetree.reconstr.IParseTreeConstructor;
import org.eclipse.xtext.resource.IResourceFactory;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
@ -89,17 +90,21 @@ public abstract class AbstractGeneratorTest extends TestCase {
return ServiceRegistry.getService(currentLanguageDescriptor, IParser.class);
}
protected IAstFactory getASTFactory() throws Exception {
protected IAstFactory getASTFactory() {
return ServiceRegistry.getService(currentLanguageDescriptor, IAstFactory.class);
}
protected IParseTreeConstructor getParseTreeConstructor() throws Exception {
protected IParseTreeConstructor getParseTreeConstructor() {
return ServiceRegistry.getService(currentLanguageDescriptor, IParseTreeConstructor.class);
}
protected IResourceFactory getResourceFactory() throws Exception {
protected IResourceFactory getResourceFactory() {
return ServiceRegistry.getService(currentLanguageDescriptor, IResourceFactory.class);
}
protected IValueConverterService getValueConverterService() {
return ServiceRegistry.getService(currentLanguageDescriptor, IValueConverterService.class);
}
// parse methods

View file

@ -30,6 +30,8 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
/**
* @author Jan Köhnlein
@ -37,78 +39,101 @@ import org.eclipse.emf.ecore.resource.Resource;
*/
public class EcoreModelComparator {
private Map<String, Object> options;
private IMatchEngine matchEngine;
private List<EStructuralFeature> ignoredFeatures = new ArrayList<EStructuralFeature>();
private Map<String, Object> options;
private IMatchEngine matchEngine;
private List<EStructuralFeature> ignoredFeatures = new ArrayList<EStructuralFeature>();
public EcoreModelComparator() {
options = new HashMap<String, Object>();
options.put(MatchOptions.OPTION_DISTINCT_METAMODELS, Boolean.TRUE);
matchEngine = new GenericMatchEngine();
}
public EcoreModelComparator() {
options = new HashMap<String, Object>();
options.put(MatchOptions.OPTION_DISTINCT_METAMODELS, Boolean.TRUE);
matchEngine = new GenericMatchEngine();
}
public boolean modelsDiffer(Resource left, Resource right) throws InterruptedException {
MatchModel matchModel = matchEngine.resourceMatch(left, right, options);
return modelsDiffer(matchModel);
}
public boolean modelsDiffer(Resource left, Resource right) throws InterruptedException {
MatchModel matchModel = matchEngine.resourceMatch(left, right, options);
return modelsDiffer(matchModel);
}
public boolean modelsDiffer(EObject left, EObject right) throws InterruptedException {
MatchModel matchModel = matchEngine.modelMatch(left, right, options);
return modelsDiffer(matchModel);
}
public boolean modelsDiffer(EObject left, EObject right) throws InterruptedException {
try {
addSyntheticResource(left);
addSyntheticResource(right);
MatchModel matchModel = matchEngine.modelMatch(left, right, options);
return modelsDiffer(matchModel);
} finally {
removeSyntheticResource(left);
removeSyntheticResource(right);
}
}
private boolean modelsDiffer(MatchModel matchModel) {
boolean modelsDiffer = false;
DiffModel diffModel = DiffService.doDiff(matchModel);
if (diffModel != null) {
for (DiffElement diffElement : diffModel.getOwnedElements()) {
modelsDiffer |= checkDiff(diffElement);
}
}
return modelsDiffer;
}
private class SyntheticResource extends ResourceImpl {
}
public void addIgnoredFeature(EStructuralFeature feature) {
ignoredFeatures.add(feature);
}
private void removeSyntheticResource(EObject o) {
if (o.eResource() instanceof SyntheticResource) {
o.eResource().getContents().clear();
}
}
private boolean checkDiff(DiffElement diffElement) {
boolean hasDiff = false;
if (!ignoreDiff(diffElement)) {
printDiff(diffElement);
hasDiff = true;
}
for (DiffElement childDiffElement : diffElement.getSubDiffElements()) {
hasDiff |= checkDiff(childDiffElement);
}
return hasDiff;
}
private void addSyntheticResource(EObject o) {
if (o.eResource() == null) {
new SyntheticResource().getContents().add(EcoreUtil.getRootContainer(o));
}
}
private boolean ignoreDiff(DiffElement diffElement) {
if (diffElement instanceof AttributeChange) {
return ignoredFeatures.contains(((AttributeChange) diffElement).getAttribute());
} else if (diffElement instanceof ReferenceChange) {
return ignoredFeatures.contains(((ReferenceChange) diffElement).getReference());
}
return diffElement instanceof DiffGroup;
}
private boolean modelsDiffer(MatchModel matchModel) {
boolean modelsDiffer = false;
DiffModel diffModel = DiffService.doDiff(matchModel);
if (diffModel != null) {
for (DiffElement diffElement : diffModel.getOwnedElements()) {
modelsDiffer |= checkDiff(diffElement);
}
}
return modelsDiffer;
}
private void printDiff(DiffElement diffElement) {
if (diffElement instanceof AttributeChange) {
AttributeChange change = (AttributeChange) diffElement;
EAttribute attribute = change.getAttribute();
System.err.println("Detected attribute difference: " + attribute.getName());
System.err.println("\t" + change.getLeftElement());
System.err.println("\t" + change.getRightElement());
} else if (diffElement instanceof ReferenceChange) {
ReferenceChange change = (ReferenceChange) diffElement;
EReference reference = change.getReference();
System.err.println("Detected reference difference: " + reference.getName());
System.err.println("\t" + change.getLeftElement());
System.err.println("\t" + change.getRightElement());
} else {
// TODO: add more sysouts here...
System.err.println(diffElement.toString());
}
}
public void addIgnoredFeature(EStructuralFeature feature) {
ignoredFeatures.add(feature);
}
private boolean checkDiff(DiffElement diffElement) {
boolean hasDiff = false;
if (!ignoreDiff(diffElement)) {
printDiff(diffElement);
hasDiff = true;
}
for (DiffElement childDiffElement : diffElement.getSubDiffElements()) {
hasDiff |= checkDiff(childDiffElement);
}
return hasDiff;
}
private boolean ignoreDiff(DiffElement diffElement) {
if (diffElement instanceof AttributeChange) {
return ignoredFeatures.contains(((AttributeChange) diffElement).getAttribute());
} else if (diffElement instanceof ReferenceChange) {
return ignoredFeatures.contains(((ReferenceChange) diffElement).getReference());
}
return diffElement instanceof DiffGroup;
}
private void printDiff(DiffElement diffElement) {
if (diffElement instanceof AttributeChange) {
AttributeChange change = (AttributeChange) diffElement;
EAttribute attribute = change.getAttribute();
System.err.println("Detected attribute difference: " + attribute.getName());
System.err.println("\t" + change.getLeftElement());
System.err.println("\t" + change.getRightElement());
} else if (diffElement instanceof ReferenceChange) {
ReferenceChange change = (ReferenceChange) diffElement;
EReference reference = change.getReference();
System.err.println("Detected reference difference: " + reference.getName());
System.err.println("\t" + change.getLeftElement() +" "+reference.getName()+" = "+change.getLeftElement().eGet(reference));
System.err.println("\t" + change.getRightElement()+" "+reference.getName()+" = "+change.getRightElement().eGet(reference));
} else {
// TODO: add more sysouts here...
System.err.println(diffElement.toString());
}
}
}