| author | Sebastian Zarnekow | 2011-08-03 10:54:27 (EDT) |
|---|---|---|
| committer | Ed Merks | 2011-08-03 10:54:27 (EDT) |
| commit | aebc3349efc8aef2d0f77d1f2930e5bde2b9e312 (patch) (side-by-side diff) | |
| tree | 5ba2d2e99f28dda8351227f83429f24d4acab33c | |
| parent | 5944281f4247f9c2682de7d725fa4b65315e815a (diff) | |
| download | org.eclipse.emf-aebc3349efc8aef2d0f77d1f2930e5bde2b9e312.zip org.eclipse.emf-aebc3349efc8aef2d0f77d1f2930e5bde2b9e312.tar.gz org.eclipse.emf-aebc3349efc8aef2d0f77d1f2930e5bde2b9e312.tar.bz2 | |
[genmodelInference] Made sure that the EcoreBuilder is used in a lazy fashion
9 files changed, 288 insertions, 40 deletions
diff --git a/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF b/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF index 3953641..47d2342 100644 --- a/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF @@ -11,5 +11,6 @@ Require-Bundle: org.eclipse.emf.ecore.xcore, org.eclipse.core.runtime;bundle-version="3.5.0";resolution:=optional, org.eclipse.xtext.junit4;bundle-version="2.0.0", org.eclipse.emf.codegen.ecore;bundle-version="2.7.0", - org.eclipse.xtext.common.types;bundle-version="2.0.0" + org.eclipse.xtext.common.types;bundle-version="2.0.0", + org.eclipse.xtext.xbase;bundle-version="2.0.0" Import-Package: org.eclipse.xtext.junit diff --git a/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/LazyGenmodelInferenceTest.java b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/LazyGenmodelInferenceTest.java new file mode 100644 index 0000000..3f593ee --- a/dev/null +++ b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/LazyGenmodelInferenceTest.java @@ -0,0 +1,131 @@ +package org.eclipse.emf.ecore.xcore.tests.scoping; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Iterator; + +import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.xcore.XcoreInjectorProvider; +import org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup; +import org.eclipse.emf.ecore.xcore.resource.XcoreResource; +import org.eclipse.xtext.common.types.TypesPackage; +import org.eclipse.xtext.junit4.InjectWith; +import org.eclipse.xtext.junit4.XtextRunner; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.IResourceDescription; +import org.eclipse.xtext.resource.IResourceDescription.Manager; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.resource.XtextResourceSet; +import org.eclipse.xtext.util.StringInputStream; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.Provider; + +@RunWith(XtextRunner.class) +@InjectWith(LazyGenmodelInferenceTest.MyXcoreInjectorProvider.class) +public class LazyGenmodelInferenceTest { + + @Inject + private Provider<XtextResourceSet> resourceSetProvider; + + public static class MyXcoreInjectorProvider extends XcoreInjectorProvider { + + private Injector injector; + + @Override + public Injector getInjector() { + if (injector == null) { + this.injector = new XcoreStandaloneSetup() { + @Override + public Injector createInjector() { + return Guice.createInjector(new org.eclipse.emf.ecore.xcore.XcoreRuntimeModule() { + public Class<? extends XtextResource> bindXtextResource() { + return InspectableXcoreResource.class; + } + }); + } + }.createInjectorAndDoEMFRegistration(); + } + return injector; + } + + @Override + public void setupRegistry() { + super.setupRegistry(); + if (injector != null) { + new XcoreStandaloneSetup().register(injector); + } + } + } + + public static class InspectableXcoreResource extends XcoreResource { + + public EList<EObject> getContentsUnsafe() { + return contents; + } + + } + + @Test + public void testSetup() { + XtextResourceSet resourceSet = resourceSetProvider.get(); + Resource resource = resourceSet.createResource(URI.createURI("foo.xcore")); + assertTrue(resource.toString(), resource instanceof InspectableXcoreResource); + assertNull(((InspectableXcoreResource)resource).getContentsUnsafe()); + } + + @Test + public void testContentsWithoutDerived() throws IOException { + XtextResourceSet resourceSet = resourceSetProvider.get(); + Resource resource = resourceSet.createResource(URI.createURI("foo.xcore")); + resource.load(new StringInputStream("package foo.bar class Baz {}"), null); + assertEquals(1, ((InspectableXcoreResource)resource).getContentsUnsafe().size()); + } + + @Test + public void testContentsWithDerived() throws IOException { + XtextResourceSet resourceSet = resourceSetProvider.get(); + Resource resource = resourceSet.createResource(URI.createURI("foo.xcore")); + resource.load(new StringInputStream("package foo.bar class Baz {}"), null); + assertTrue(1 < resource.getContents().size()); + } + + public void testResourceDescriptionManagerDoesNotResolve() throws IOException { + XtextResourceSet resourceSet = resourceSetProvider.get(); + InspectableXcoreResource resource = (InspectableXcoreResource) resourceSet.createResource(URI.createURI("foo.xcore")); + resource.load(new StringInputStream("package foo.bar class Baz {}"), null); + Manager manager = resource.getResourceServiceProvider().getResourceDescriptionManager(); + IResourceDescription resourceDescription = manager.getResourceDescription(resource); + + Iterator<IEObjectDescription> eclass = resourceDescription.getExportedObjectsByType(EcorePackage.Literals.ECLASS) + .iterator(); + Iterator<IEObjectDescription> genclass = resourceDescription.getExportedObjectsByType( + GenModelPackage.Literals.GEN_CLASS).iterator(); + Iterator<IEObjectDescription> jvmTypes = resourceDescription.getExportedObjectsByType( + TypesPackage.Literals.JVM_GENERIC_TYPE).iterator(); + final String expected = "foo.bar.Baz"; + assertEquals(expected, eclass.next().getName().toString()); + assertFalse(eclass.hasNext()); + assertEquals(expected, genclass.next().getName().toString()); + assertFalse(genclass.hasNext()); + assertEquals(expected, jvmTypes.next().getName().toString()); + assertEquals(expected + "Impl", jvmTypes.next().getName().toString()); + assertFalse(genclass.hasNext()); + + assertEquals(1, resource.getContentsUnsafe().size()); + } + +} diff --git a/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java index 527939b..2aa8ec4 100644 --- a/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java +++ b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java @@ -51,5 +51,5 @@ public class ResourceDescriptionManagerTest assertEquals(expected + "Impl", jvmTypes.next().getName().toString()); assertFalse(genclass.hasNext()); } - + } diff --git a/org.eclipse.emf.ecore.xcore/META-INF/MANIFEST.MF b/org.eclipse.emf.ecore.xcore/META-INF/MANIFEST.MF index 21ee1e0..3844c81 100644 --- a/org.eclipse.emf.ecore.xcore/META-INF/MANIFEST.MF +++ b/org.eclipse.emf.ecore.xcore/META-INF/MANIFEST.MF @@ -26,6 +26,7 @@ Export-Package: org.eclipse.emf.ecore.xcore, org.eclipse.emf.ecore.xcore.linking,
org.eclipse.emf.ecore.xcore.parser.antlr,
org.eclipse.emf.ecore.xcore.parser.antlr.internal,
+ org.eclipse.emf.ecore.xcore.resource,
org.eclipse.emf.ecore.xcore.scoping,
org.eclipse.emf.ecore.xcore.services,
org.eclipse.emf.ecore.xcore.util,
diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java index 4b28f6e..c4fc393 100644 --- a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java @@ -7,10 +7,12 @@ import org.eclipse.emf.ecore.xcore.linking.XcoreLazyLinker; import org.eclipse.emf.ecore.xcore.resource.XcoreResource; import org.eclipse.emf.ecore.xcore.scoping.XcoreImportedNamespaceAwareScopeProvider; import org.eclipse.emf.ecore.xcore.scoping.XcoreQualifiedNameProvider; +import org.eclipse.emf.ecore.xcore.scoping.XcoreResourceDescriptionManager; import org.eclipse.emf.ecore.xcore.scoping.XcoreResourceDescriptionStrategy; import org.eclipse.xtext.linking.ILinker; import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; +import org.eclipse.xtext.resource.IResourceDescription; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.scoping.IScopeProvider; import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; @@ -60,5 +62,9 @@ public class XcoreRuntimeModule extends org.eclipse.emf.ecore.xcore.AbstractXcor binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(XcoreImportedNamespaceAwareScopeProvider.class); } + public Class<? extends IResourceDescription.Manager> bindIResourceDescriptionManager() { + return XcoreResourceDescriptionManager.class; + } + } diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/linking/XcoreLazyLinker.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/linking/XcoreLazyLinker.java index d7b5c1a..c17a1c3 100644 --- a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/linking/XcoreLazyLinker.java +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/linking/XcoreLazyLinker.java @@ -1,20 +1,10 @@ package org.eclipse.emf.ecore.xcore.linking;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-import java.util.Collections;
import java.util.Iterator;
-import org.eclipse.emf.codegen.ecore.genmodel.GenBase;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
-import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.xcore.XPackage;
-import org.eclipse.emf.ecore.xcore.util.XcoreEcoreBuilder;
import org.eclipse.xtext.diagnostics.IDiagnosticConsumer;
import org.eclipse.xtext.parser.antlr.IReferableElementsUnloader;
import org.eclipse.xtext.xbase.jvmmodel.JvmModelXbaseLazyLinker;
@@ -40,38 +30,13 @@ public class XcoreLazyLinker extends JvmModelXbaseLazyLinker i.remove();
}
}
-
super.beforeModelLinked(model, diagnosticsConsumer);
}
+
@Override
protected void afterModelLinked(EObject model, IDiagnosticConsumer diagnosticsConsumer)
{
- if (model instanceof XPackage)
- {
- XcoreEcoreBuilder xcoreEcoreBuilder = new XcoreEcoreBuilder();
- EPackage ePackage = xcoreEcoreBuilder.getEPackage((XPackage)model);
- model.eResource().getContents().add(ePackage);
- GenModel genModel = GenModelFactory.eINSTANCE.createGenModel();
- genModel.initialize(Collections.singleton(ePackage));
- model.eResource().getContents().add(genModel);
- genModel.initialize();
- for (Iterator<EObject> i = genModel.eAllContents(); i.hasNext(); )
- {
- EObject eObject = i.next();
- if (eObject instanceof GenBase)
- {
- GenBase genBase = (GenBase)eObject;
- EModelElement eModelElement = genBase.getEcoreModelElement();
- if (eModelElement != null)
- {
- XcoreEcoreBuilder.map(eModelElement, (GenBase)eObject);
- }
- }
- }
-
- xcoreEcoreBuilder.link();
- }
- super.afterModelLinked(model, diagnosticsConsumer);
+ // do nothing
}
}
diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/resource/XcoreResource.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/resource/XcoreResource.java index df02b51..6fe890b 100644 --- a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/resource/XcoreResource.java +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/resource/XcoreResource.java @@ -1,11 +1,21 @@ package org.eclipse.emf.ecore.xcore.resource; +import java.util.Collections; +import java.util.Iterator; + +import org.eclipse.emf.codegen.ecore.genmodel.GenBase; +import org.eclipse.emf.codegen.ecore.genmodel.GenModel; +import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EModelElement; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xcore.XPackage; import org.eclipse.emf.ecore.xcore.scoping.LazyCreationProxyUriConverter; +import org.eclipse.emf.ecore.xcore.util.XcoreEcoreBuilder; import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.parser.IParseResult; @@ -45,7 +55,31 @@ public class XcoreResource extends XbaseResource { } protected void lateInitialize() { - + if (getParseResult() != null && getParseResult().getRootASTElement() instanceof XPackage) + { + XPackage model = (XPackage) getParseResult().getRootASTElement(); + XcoreEcoreBuilder xcoreEcoreBuilder = new XcoreEcoreBuilder(); + EPackage ePackage = xcoreEcoreBuilder.getEPackage(model); + super.getContents().add(ePackage); + GenModel genModel = GenModelFactory.eINSTANCE.createGenModel(); + genModel.initialize(Collections.singleton(ePackage)); + super.getContents().add(genModel); + genModel.initialize(); + for (Iterator<EObject> i = genModel.eAllContents(); i.hasNext(); ) + { + EObject eObject = i.next(); + if (eObject instanceof GenBase) + { + GenBase genBase = (GenBase)eObject; + EModelElement eModelElement = genBase.getEcoreModelElement(); + if (eModelElement != null) + { + XcoreEcoreBuilder.map(eModelElement, (GenBase)eObject); + } + } + } + xcoreEcoreBuilder.link(); + } } @Override diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescription.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescription.java new file mode 100644 index 0000000..dc61e6c --- a/dev/null +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescription.java @@ -0,0 +1,83 @@ +package org.eclipse.emf.ecore.xcore.scoping; + +import static com.google.common.collect.Lists.newArrayList; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.parser.IParseResult; +import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.resource.impl.DefaultResourceDescription; +import org.eclipse.xtext.util.IAcceptor; +import org.eclipse.xtext.util.IResourceScopeCache; + +/** + * This implementation ensures that the contents of the resource is not queried + * to compute the exported elements. + * @author Sebastian Zarnekow + */ +public class XcoreResourceDescription extends DefaultResourceDescription +{ + + private final static Logger log = Logger.getLogger(XcoreResourceDescription.class); + private final IDefaultResourceDescriptionStrategy strategy; + + public XcoreResourceDescription(Resource resource, IDefaultResourceDescriptionStrategy strategy, + IResourceScopeCache cache) + { + super(resource, strategy, cache); + this.strategy = strategy; + } + + @Override + protected List<IEObjectDescription> computeExportedObjects() + { + Resource resource = getResource(); + if (resource instanceof XtextResource) + { + if (resource.isLoaded()) + { + try + { + resource.load(null); + } catch (IOException e) + { + log.error(e.getMessage(), e); + return Collections.<IEObjectDescription> emptyList(); + } + } + IParseResult parseResult = ((XtextResource) resource).getParseResult(); + if (parseResult != null && parseResult.getRootASTElement() != null) + { + final List<IEObjectDescription> result = newArrayList(); + IAcceptor<IEObjectDescription> acceptor = new IAcceptor<IEObjectDescription>() + { + public void accept(IEObjectDescription description) + { + result.add(description); + } + }; + TreeIterator<EObject> allProperContents = EcoreUtil2.eAll(parseResult.getRootASTElement()); + while (allProperContents.hasNext()) + { + EObject content = allProperContents.next(); + if (!strategy.createEObjectDescriptions(content, acceptor)) + { + allProperContents.prune(); + } + } + return result; + } + } + return super.computeExportedObjects(); + } + +} diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescriptionManager.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescriptionManager.java new file mode 100644 index 0000000..fbfb78e --- a/dev/null +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescriptionManager.java @@ -0,0 +1,27 @@ +package org.eclipse.emf.ecore.xcore.scoping; + +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; +import org.eclipse.xtext.resource.IResourceDescription; +import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager; + +import com.google.inject.Singleton; + +/** + * The resource description manager for Xcore resources. It produces an {@link XcoreResourceDescription} + * which allows to produce descriptions without iterating the derived contents of the resource. + * + * @author Sebastian Zarnekow + */ +@Singleton +public class XcoreResourceDescriptionManager extends DefaultResourceDescriptionManager +{ + + @Override + protected IResourceDescription internalGetResourceDescription(Resource resource, + IDefaultResourceDescriptionStrategy strategy) + { + return new XcoreResourceDescription(resource, strategy, getCache()); + } + +} |

