use of org.eclipse.xtext.resource.IResourceDescriptions in project n4js by eclipse.
the class N4JSResource method doResolveProxy.
/**
* Invoked from {@link ProxyResolvingEObjectImpl#eResolveProxy(InternalEObject)} whenever an EMF proxy inside an
* N4JSResource is being resolved. The receiving resource is the resource containing the proxy, not necessarily the
* resource the proxy points to.
*
* @param proxy
* the proxy to resolve.
* @param objectContext
* the {@code EObject} contained in this resource that holds the given proxy.
*/
@Override
public EObject doResolveProxy(InternalEObject proxy, EObject objectContext) {
// step 0: ensure proxy resolution is allowed
// (this must be checked before calling #performPostProcessing(), because that would trigger initialization if
// not done already)
// NOTE: we decided not to add a fail fast check here, mostly because we cannot distinguish between whether the
// resolution was triggered by our internal N4JS implementation or by client code; for a detailed discussion
// see Section 9.11.4. "When is Proxy Resolution Allowed?" in the design document and GH-219.
// step 1: trigger post processing of the resource containing 'proxy' iff it is the first proxy being resolved
// (if another proxy has been resolved before, post processing will already be running/completed, and in that
// case the next line will simply do nothing, cf. #performPostProcessing())
this.performPostProcessing();
// step 2: now turn to resolving the proxy at hand
final URI targetUri = proxy.eProxyURI();
final boolean isLazyLinkingProxy = getEncoder().isCrossLinkFragment(this, targetUri.fragment());
if (!isLazyLinkingProxy) {
// we have an ordinary EMF proxy (not one of Xtext's lazy linking proxies) ...
final ResourceSet resSet = getResourceSet();
final URI targetResourceUri = targetUri.trimFragment();
final String targetFileExt = targetResourceUri.fileExtension();
if (N4JSGlobals.N4JS_FILE_EXTENSION.equals(targetFileExt) || N4JSGlobals.N4JSD_FILE_EXTENSION.equals(targetFileExt) || N4JSGlobals.N4JSX_FILE_EXTENSION.equals(targetFileExt)) {
// proxy is pointing into an .n4js or .n4jsd file ...
// check if we can work with the TModule from the index or if it is mandatory to load from source
final boolean canLoadFromDescription = !targetUri.fragment().startsWith("/0") && canLoadFromDescriptionHelper.canLoadFromDescription(targetResourceUri, getResourceSet());
if (canLoadFromDescription) {
final String targetFragment = targetUri.fragment();
final Resource targetResource = resSet.getResource(targetResourceUri, false);
// if targetResource is not loaded yet, try to load it from index first
if (targetResource == null) {
if (targetFragment != null && (targetFragment.equals("/1") || targetFragment.startsWith("/1/"))) {
// uri points to a TModule element in a resource not yet contained in our resource set
// --> try to load target resource from index
final IResourceDescriptions index = n4jsCore.getXtextIndex(resSet);
final IResourceDescription resDesc = index.getResourceDescription(targetResourceUri);
if (resDesc != null) {
// next line will add the new resource to resSet.resources
n4jsCore.loadModuleFromIndex(resSet, resDesc, false);
}
}
}
}
final EObject targetObject;
try {
// standard behavior:
// obtain target EObject from targetResource in the usual way
// (might load targetResource from disk if it wasn't loaded from index above)
targetObject = resSet.getEObject(targetUri, true);
} catch (Exception fnf) {
if (fnf.getCause() instanceof FileNotFoundException) {
// This happens for instance when an external library was removed,
// but another external library depends on the removed one.
LOGGER.warn("File not found during proxy resolution", fnf);
return proxy;
}
throw fnf;
}
// is always marked as fullyPostProcessed==true)
if (targetObject != null && (this.isPostProcessing() || this.isFullyProcessed())) {
final Resource targetResource2 = targetObject.eResource();
if (targetResource2 instanceof N4JSResource) {
// no harm done, if already running/completed
((N4JSResource) targetResource2).performPostProcessing();
}
}
// important: return proxy itself if unresolvable!
return targetObject != null ? targetObject : proxy;
}
}
// --> above special handling not required, so just apply EMF's default resolution behavior
return EcoreUtil.resolve(proxy, this);
}
use of org.eclipse.xtext.resource.IResourceDescriptions in project dsl-devkit by dsldevkit.
the class CachingStateBasedContainerManager method createContainer.
@Override
protected synchronized IContainer createContainer(final String handle, final IResourceDescriptions resourceDescriptions) {
final IResourceDescriptions descriptionsKey = resourceDescriptions instanceof CurrentDescriptions2.ResourceSetAware ? ((CurrentDescriptions2.ResourceSetAware) resourceDescriptions).getDelegate() : resourceDescriptions;
Map<String, WeakReference<IContainer>> containersMap = descriptionsContainersCache.get(descriptionsKey);
if (containersMap == null) {
containersMap = new HashMap<String, WeakReference<IContainer>>();
descriptionsContainersCache.put(descriptionsKey, containersMap);
}
WeakReference<IContainer> containerRef = containersMap.get(handle);
IContainer container = containerRef != null ? containerRef.get() : null;
if (container == null) {
final IContainerState containerState = new ContainerState(handle, getStateProvider().get(descriptionsKey));
container = new StateBasedContainerWithHandle(descriptionsKey, containerState, handle);
new CacheInvalidator(descriptionsKey, handle, containerState);
containerRef = new WeakReference<IContainer>(container);
containersMap.put(handle, containerRef);
}
return container;
}
use of org.eclipse.xtext.resource.IResourceDescriptions in project dsl-devkit by dsldevkit.
the class AbstractPolymorphicScopeProvider method getVisibleContainers.
/**
* Return the visible containers given a context object.
*
* @param context
* The context object
* @param originalResource
* the original resource
* @return The list of visible containers.
*/
protected List<IContainer> getVisibleContainers(final EObject context, final Resource originalResource) {
// NOPMD by WTH on 26.01.11 09:26 (NPath
// complexity...)
final Resource ctxRsc = originalResource == null ? context.eResource() : originalResource;
if (!(ctxRsc instanceof XtextResource)) {
// $NON-NLS-1$ //$NON-NLS-2$
LOGGER.error(MessageFormat.format("Context {0} is not in an Xtext resource: {1}", context, ctxRsc != null ? ctxRsc.getURI() : "null"));
throw new IllegalStateException();
}
final XtextResource rsc = (XtextResource) ctxRsc;
// Cache these container lists, they're expensive to create
// $NON-NLS-1$
final String key = "CONTAINERCACHE&" + rsc.getURI().toString();
List<IContainer> result = null;
// $NON-NLS-1$
final ResourceCache<String, List<IContainer>> cache = CacheManager.getInstance().getOrCreateResourceCache("AbstractPolymorphicScopeProvider#cache", rsc);
if (cache != null) {
result = cache.get(key);
if (result != null) {
return result;
}
}
final EObject ctx = ctxRsc != context.eResource() ? ctxRsc.getContents().get(0) : context;
// We need to get the container manager dynamically, otherwise we may end up using the wrong ResourceDescriptions if
// the context object in actually from another resource.
final IResourceServiceProvider resourceServiceProvider = rsc.getResourceServiceProvider();
final IResourceDescription.Manager descriptionManager = resourceServiceProvider.getResourceDescriptionManager();
final IContainer.Manager containerManager = resourceServiceProvider.getContainerManager();
final IResourceDescription description = descriptionManager.getResourceDescription(ctx.eResource());
final IResourceDescriptions resourceDescriptions = getResourceDescriptions(ctx.eResource());
result = containerManager.getVisibleContainers(description, resourceDescriptions);
if (cache != null) {
cache.set(key, result);
}
return result;
}
use of org.eclipse.xtext.resource.IResourceDescriptions in project dsl-devkit by dsldevkit.
the class EPackageScopeProvider method scope_EPackage.
/**
* Scope for {@link EPackage}. These are read from the registry as well as from the {@link Grammar Xtext grammar} corresponding
* to the scope model (if any).
*
* @param context
* context scope DSL model (usually the root element, but any object will do)
* @param reference
* context reference (unused for the time being)
* @return scope with all available {@link EPackage EPackages} with {@link EPackage#getNsURI()} as name
*/
// CHECKSTYLE:OFF
public IScope scope_EPackage(final EObject context, final EReference reference) {
// CHECKSTYLE:ON
Resource rsc = context.eResource();
IScope result = IScope.NULLSCOPE;
// Add packages from the registry first.
final Registry packageRegistry = EPackage.Registry.INSTANCE;
result = new AbstractScope(result, false) {
@Override
protected IEObjectDescription getSingleLocalElementByName(final QualifiedName name) {
return getEPackage(nameConverter.toString(name));
}
@Override
protected Iterable<IEObjectDescription> getAllLocalElements() {
return Iterables.filter(Iterables.transform(Sets.newHashSet(packageRegistry.keySet()), this::getEPackage), Predicates.notNull());
}
private IEObjectDescription getEPackage(final String nsURI) {
try {
EPackage ePackage = packageRegistry.getEPackage(nsURI);
return ePackage != null ? EObjectDescription.create(QualifiedName.create(nsURI), ePackage) : null;
// CHECKSTYLE:OFF
} catch (Exception e) {
// CHECKSTYLE:ON
// $NON-NLS-1$
LOG.warn("could not load package " + nsURI, e);
return null;
}
}
};
// Add the index
IResourceDescriptions descriptions = descriptionsProvider.getResourceDescriptions(context.eResource());
if (descriptions != null) {
result = SelectableBasedScope.createScope(result, descriptions, EcorePackage.Literals.EPACKAGE, false);
}
// Add the global scope
result = SelectableBasedScope.createScope(result, new ScopeBasedSelectable(globalScopeProvider.getScope(rsc, reference, null)), EcorePackage.Literals.EPACKAGE, false);
// Now add all packages from the grammar
final URI grammarUri = rsc.getURI().trimFileExtension().appendFileExtension(XTEXT_EXTENSION);
final ResourceSet resourceSet = rsc.getResourceSet();
final URIConverter uriConverter = resourceSet.getURIConverter();
if (uriConverter.exists(grammarUri, null)) {
final Resource grammarResource = resourceSet.getResource(grammarUri, true);
if (grammarResource != null && !grammarResource.getContents().isEmpty()) {
final Grammar grammar = (Grammar) grammarResource.getContents().get(0);
final IScope parent = result;
result = new SimpleScope(parent, Iterables.transform(Iterables.filter(getGrammarEPackages(grammar), Predicates.notNull()), new Function<EPackage, IEObjectDescription>() {
@Override
public IEObjectDescription apply(final EPackage param) {
return EObjectDescription.create(param.getNsURI(), param);
}
}));
}
}
return result;
}
use of org.eclipse.xtext.resource.IResourceDescriptions in project dsl-devkit by dsldevkit.
the class LinkingService method importObject.
/**
* Register a name as imported.
*
* @param context
* context object within which a reference is being set to some object using "name" for the lookup, must not be {@code null}
* @param name
* the lookup name, may be {@code null}
* @param type
* the lookup type, may be {@code null}
* @param target
* the associated target eObject. If not {@code null} then all names for this eObject are also recorded
* as imported, provided they're not the same as the {@code name} parameter. May be {@code null}
*/
public void importObject(final EObject context, final String name, final EObject target, final EClass type) {
// import exported name for resolved references
ImportedNamesTypesAdapter adapter = getImportedNamesAdapter(context);
if (target != null) {
QualifiedName targetName = null;
final IResourceDescriptions resourceDescriptions = provider.getResourceDescriptions(context.eResource());
Iterator<IEObjectDescription> exports = resourceDescriptions.getExportedObjectsByObject(target).iterator();
if (exports.hasNext()) {
targetName = exports.next().getName();
if (targetName != null && !targetName.isEmpty()) {
// NOPMD targetName not a String!
final QualifiedName lowerCaseName = targetName.toLowerCase();
adapter.getImportedNames().add(lowerCaseName);
if (adapter.getImportedNamesTypes().containsKey(lowerCaseName)) {
adapter.getImportedNamesTypes().get(lowerCaseName).add(type);
} else {
adapter.getImportedNamesTypes().put(lowerCaseName, Sets.newHashSet(type));
}
}
}
} else if (name != null && name.length() > 0) {
// import parsed string for unresolved references
QualifiedName unresolvedName = crossRefHelper.toUnresolvedReferenceName(name);
adapter.getImportedNames().add(unresolvedName);
if (adapter.getImportedNamesTypes().containsKey(unresolvedName)) {
adapter.getImportedNamesTypes().get(unresolvedName).add(type);
} else {
adapter.getImportedNamesTypes().put(unresolvedName, Sets.newHashSet(type));
}
}
}
Aggregations