mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
Merge pull request #1423 from eclipse/ade-refactor-xtend-to-java
[eclipse/xtext#1679] Refactor more Xtend to java.
This commit is contained in:
commit
2f5ad0017f
27 changed files with 1117 additions and 2374 deletions
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.preferences;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
|
||||
public class PreferenceValuesByLanguage {
|
||||
private final Map<String, IPreferenceValues> preferencesByLanguage = new HashMap<>();
|
||||
|
||||
public IPreferenceValues get(String languageId) {
|
||||
return preferencesByLanguage.get(languageId);
|
||||
}
|
||||
|
||||
public IPreferenceValues put(String languageId, IPreferenceValues values) {
|
||||
return preferencesByLanguage.put(languageId, values);
|
||||
}
|
||||
|
||||
public static PreferenceValuesByLanguage findInEmfObject(Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters())
|
||||
if (adapter instanceof PreferenceValuesByLanguageAdapter)
|
||||
return ((PreferenceValuesByLanguageAdapter) adapter).get();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PreferenceValuesByLanguage removeFromEmfObject(Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for (int i = 0; i < adapters.size(); i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof PreferenceValuesByLanguageAdapter)
|
||||
return ((PreferenceValuesByLanguageAdapter) emfObject.eAdapters().remove(i)).get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(Notifier emfObject) {
|
||||
if (findInEmfObject(emfObject) != null)
|
||||
throw new IllegalStateException(
|
||||
"The given EMF object already contains an adapter for PreferenceValuesByLanguage");
|
||||
PreferenceValuesByLanguageAdapter adapter = new PreferenceValuesByLanguageAdapter(this);
|
||||
emfObject.eAdapters().add(adapter);
|
||||
}
|
||||
|
||||
public static class PreferenceValuesByLanguageAdapter extends AdapterImpl {
|
||||
private PreferenceValuesByLanguage element;
|
||||
|
||||
public PreferenceValuesByLanguageAdapter(PreferenceValuesByLanguage element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public PreferenceValuesByLanguage get() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(Object object) {
|
||||
return object == PreferenceValuesByLanguage.class;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.preferences
|
||||
|
||||
import java.util.Map
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable
|
||||
|
||||
@EmfAdaptable class PreferenceValuesByLanguage {
|
||||
val Map<String, IPreferenceValues> preferencesByLanguage = newHashMap
|
||||
|
||||
def get(String languageId) {
|
||||
preferencesByLanguage.get(languageId)
|
||||
}
|
||||
|
||||
def put(String languageId, IPreferenceValues values) {
|
||||
preferencesByLanguage.put(languageId, values)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Copyright (c) 2014, 2020 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource;
|
||||
|
||||
import org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtext.service.OperationCanceledError;
|
||||
import org.eclipse.xtext.service.OperationCanceledManager;
|
||||
import org.eclipse.xtext.util.CancelIndicator;
|
||||
import org.eclipse.xtext.util.concurrent.CancelableUnitOfWork;
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public class OutdatedStateManager {
|
||||
@Inject
|
||||
private OperationCanceledManager canceledManager;
|
||||
|
||||
private final ThreadLocal<Boolean> cancelationAllowed = new ThreadLocal<Boolean>() {
|
||||
@Override
|
||||
public Boolean initialValue() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Created a fresh CancelIndicator
|
||||
*/
|
||||
public CancelIndicator newCancelIndicator(ResourceSet rs) {
|
||||
if (rs instanceof XtextResourceSet) {
|
||||
boolean isCancelationAllowed = cancelationAllowed.get().booleanValue();
|
||||
XtextResourceSet xtextRs = (XtextResourceSet) rs;
|
||||
int current = xtextRs.getModificationStamp();
|
||||
return () -> isCancelationAllowed && (xtextRs.isOutdated() || current != xtextRs.getModificationStamp());
|
||||
} else {
|
||||
return CancelIndicator.NullImpl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given ResourceSet is in an outdated state and throws an {@link OperationCanceledError} if so.
|
||||
*/
|
||||
public void checkCanceled(ResourceSet rs) {
|
||||
if (rs instanceof XtextResourceSet)
|
||||
if (((XtextResourceSet) rs).isOutdated() && cancelationAllowed.get().booleanValue())
|
||||
canceledManager.throwOperationCanceledException();
|
||||
}
|
||||
|
||||
public <R extends Object, P extends Resource> R exec(IUnitOfWork<R, P> work, P param) {
|
||||
Boolean wasCancelationAllowed = cancelationAllowed.get();
|
||||
try {
|
||||
if (work instanceof CancelableUnitOfWork) {
|
||||
((CancelableUnitOfWork<?, ?>) work)
|
||||
.setCancelIndicator((param == null) ? () -> true : newCancelIndicator(param.getResourceSet()));
|
||||
} else {
|
||||
cancelationAllowed.set(false);
|
||||
}
|
||||
return work.exec(param);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
cancelationAllowed.set(wasCancelationAllowed);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet
|
||||
import org.eclipse.xtext.service.OperationCanceledError
|
||||
import org.eclipse.xtext.service.OperationCanceledManager
|
||||
import org.eclipse.xtext.util.CancelIndicator
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork
|
||||
import org.eclipse.xtext.util.concurrent.CancelableUnitOfWork
|
||||
import org.eclipse.emf.ecore.resource.Resource
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
class OutdatedStateManager {
|
||||
|
||||
@Inject OperationCanceledManager canceledManager
|
||||
|
||||
val cancelationAllowed = new ThreadLocal<Boolean> {
|
||||
override initialValue() {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created a fresh CancelIndicator
|
||||
*/
|
||||
def CancelIndicator newCancelIndicator(ResourceSet rs) {
|
||||
if (rs instanceof XtextResourceSet) {
|
||||
val boolean cancelationAllowed = this.cancelationAllowed.get
|
||||
val current = rs.modificationStamp
|
||||
return [
|
||||
cancelationAllowed && (rs.isOutdated || current != rs.modificationStamp)
|
||||
]
|
||||
} else {
|
||||
CancelIndicator.NullImpl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given ResourceSet is in an outdated state and
|
||||
* throws an {@link OperationCanceledError} if so.
|
||||
*/
|
||||
def void checkCanceled(ResourceSet rs) {
|
||||
if (rs instanceof XtextResourceSet) {
|
||||
if (rs.outdated && cancelationAllowed.get)
|
||||
canceledManager.throwOperationCanceledException()
|
||||
}
|
||||
}
|
||||
|
||||
def <R, P extends Resource> R exec(IUnitOfWork<R, P> work, P param) {
|
||||
val wasCancelationAllowed = cancelationAllowed.get
|
||||
try {
|
||||
if (work instanceof CancelableUnitOfWork<?,?>) {
|
||||
work.cancelIndicator = if (param === null)
|
||||
[ true ]
|
||||
else
|
||||
param.resourceSet.newCancelIndicator
|
||||
} else {
|
||||
cancelationAllowed.set(false)
|
||||
}
|
||||
work.exec(param)
|
||||
} finally {
|
||||
cancelationAllowed.set(wasCancelationAllowed)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Copyright (c) 2016, 2020 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import org.eclipse.xtext.ISetup;
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider.Registry;
|
||||
import org.eclipse.xtext.resource.impl.ResourceServiceProviderRegistryImpl;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
* @since 2.11
|
||||
*/
|
||||
@Singleton
|
||||
public class ResourceServiceProviderServiceLoader implements Provider<Registry> {
|
||||
|
||||
private final ServiceLoader<ISetup> setupLoader = ServiceLoader.load(ISetup.class);
|
||||
|
||||
private final Registry registry = loadRegistry();
|
||||
|
||||
private Registry loadRegistry() {
|
||||
ResourceServiceProviderRegistryImpl registry = new ResourceServiceProviderRegistryImpl();
|
||||
for (ISetup cp : setupLoader) {
|
||||
Injector injector = cp.createInjectorAndDoEMFRegistration();
|
||||
IResourceServiceProvider resourceServiceProvider = injector.getInstance(IResourceServiceProvider.class);
|
||||
FileExtensionProvider extensionProvider = injector.getInstance(FileExtensionProvider.class);
|
||||
String primaryFileExtension = extensionProvider.getPrimaryFileExtension();
|
||||
for (String ext : extensionProvider.getFileExtensions()) {
|
||||
if (registry.getExtensionToFactoryMap().containsKey(ext)) {
|
||||
if (primaryFileExtension.equals(ext))
|
||||
registry.getExtensionToFactoryMap().put(ext, resourceServiceProvider);
|
||||
} else {
|
||||
registry.getExtensionToFactoryMap().put(ext, resourceServiceProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceServiceProvider.Registry get() {
|
||||
return this.registry;
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource
|
||||
|
||||
import com.google.inject.Provider
|
||||
import java.util.ServiceLoader
|
||||
import org.eclipse.xtext.ISetup
|
||||
import org.eclipse.xtext.resource.FileExtensionProvider
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider
|
||||
import org.eclipse.xtext.resource.impl.ResourceServiceProviderRegistryImpl
|
||||
import com.google.inject.Singleton
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
* @since 2.11
|
||||
*/
|
||||
@Singleton
|
||||
class ResourceServiceProviderServiceLoader implements Provider<IResourceServiceProvider.Registry> {
|
||||
|
||||
ServiceLoader<ISetup> setupLoader = ServiceLoader.load(ISetup)
|
||||
|
||||
IResourceServiceProvider.Registry registry = loadRegistry
|
||||
|
||||
private def IResourceServiceProvider.Registry loadRegistry() {
|
||||
val registry = new ResourceServiceProviderRegistryImpl()
|
||||
for (ISetup cp : setupLoader) {
|
||||
val injector = cp.createInjectorAndDoEMFRegistration();
|
||||
val resourceServiceProvider = injector.getInstance(IResourceServiceProvider)
|
||||
val extensionProvider = injector.getInstance(FileExtensionProvider)
|
||||
for (ext : extensionProvider.fileExtensions) {
|
||||
if (registry.extensionToFactoryMap.containsKey(ext)) {
|
||||
if (extensionProvider.primaryFileExtension == ext) {
|
||||
registry.extensionToFactoryMap.put(ext, resourceServiceProvider)
|
||||
}
|
||||
} else {
|
||||
registry.extensionToFactoryMap.put(ext, resourceServiceProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
override get() {
|
||||
return registry
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* Copyright (c) 2017, 2020 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.containers;
|
||||
|
||||
import static com.google.common.collect.Iterables.*;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.size;
|
||||
import static org.eclipse.xtext.xbase.lib.IterableExtensions.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
|
||||
import org.eclipse.xtext.naming.QualifiedName;
|
||||
import org.eclipse.xtext.resource.IContainer;
|
||||
import org.eclipse.xtext.resource.IEObjectDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.impl.ChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.LiveShadowedChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData;
|
||||
import org.eclipse.xtext.workspace.IProjectConfig;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.14
|
||||
*/
|
||||
@Beta
|
||||
public class LiveShadowedChunkedContainer implements IContainer {
|
||||
private final LiveShadowedChunkedResourceDescriptions descriptions;
|
||||
|
||||
private final String containerName;
|
||||
|
||||
private IProjectConfig projectConfig;
|
||||
|
||||
private boolean isProjectConfigSet = false;
|
||||
|
||||
public LiveShadowedChunkedContainer(LiveShadowedChunkedResourceDescriptions descriptions, String containerName) {
|
||||
this.descriptions = descriptions;
|
||||
this.containerName = containerName;
|
||||
}
|
||||
|
||||
protected ChunkedResourceDescriptions getChunkedResourceDescriptions() {
|
||||
return (ChunkedResourceDescriptions) descriptions.getGlobalDescriptions();
|
||||
}
|
||||
|
||||
protected IProjectConfig getProjectConfig() {
|
||||
if (!isProjectConfigSet) {
|
||||
projectConfig = descriptions.getWorkspaceConfig() == null ? null
|
||||
: descriptions.getWorkspaceConfig().findProjectByName(containerName);
|
||||
isProjectConfigSet = true;
|
||||
}
|
||||
return projectConfig;
|
||||
}
|
||||
|
||||
protected ResourceDescriptionsData getChunk() {
|
||||
ResourceDescriptionsData container = getChunkedResourceDescriptions().getContainer(containerName);
|
||||
if (container != null)
|
||||
return container;
|
||||
return new ResourceDescriptionsData(Collections.emptyList());
|
||||
}
|
||||
|
||||
protected Iterable<IResourceDescription> getContainedLocalDescriptions() {
|
||||
return filter(descriptions.getLocalDescriptions().getAllResourceDescriptions(), it -> isContained(it.getURI()));
|
||||
}
|
||||
|
||||
protected boolean isContained(URI uri) {
|
||||
return (getChunk().getResourceDescription(uri) != null)
|
||||
|| (getProjectConfig() != null && getProjectConfig().findSourceFolderContaining(uri) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceDescription getResourceDescription(URI uri) {
|
||||
return isContained(uri) ? descriptions.getResourceDescription(uri) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResourceDescriptionCount() {
|
||||
return size(getResourceDescriptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IResourceDescription> getResourceDescriptions() {
|
||||
Set<URI> localURIs = getExistingOrRenamedResourceURIs();
|
||||
return concat(getContainedLocalDescriptions(),
|
||||
filter(getChunk().getAllResourceDescriptions(), it -> !localURIs.contains(it.getURI())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResourceDescription(URI uri) {
|
||||
return getChunk().getResourceDescription(uri) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjects() {
|
||||
Set<URI> localURIs = getExistingOrRenamedResourceURIs();
|
||||
return concat(concat(map(getContainedLocalDescriptions(), it -> it.getExportedObjects())),
|
||||
filter(getChunk().getExportedObjects(), it -> !localURIs.contains(it.getEObjectURI().trimFragment())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjects(EClass type, QualifiedName name, boolean ignoreCase) {
|
||||
Set<URI> localURIs = getExistingOrRenamedResourceURIs();
|
||||
return concat(concat(map(getContainedLocalDescriptions(), it -> it.getExportedObjects(type, name, ignoreCase))),
|
||||
filter(getChunk().getExportedObjects(type, name, ignoreCase),
|
||||
it -> !localURIs.contains(it.getEObjectURI().trimFragment())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjectsByObject(final EObject object) {
|
||||
Set<URI> localURIs = getExistingOrRenamedResourceURIs();
|
||||
return concat(concat(map(getContainedLocalDescriptions(), it -> it.getExportedObjectsByObject(object))),
|
||||
filter(getChunk().getExportedObjectsByObject(object),
|
||||
it -> !localURIs.contains(it.getEObjectURI().trimFragment())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjectsByType(EClass type) {
|
||||
Set<URI> localURIs = getExistingOrRenamedResourceURIs();
|
||||
return concat(concat(map(getContainedLocalDescriptions(), it -> it.getExportedObjectsByType(type))),
|
||||
filter(getChunk().getExportedObjectsByType(type),
|
||||
it -> !localURIs.contains(it.getEObjectURI().trimFragment())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return IterableExtensions.isEmpty(getContainedLocalDescriptions()) && getChunk().isEmpty();
|
||||
}
|
||||
|
||||
protected Set<URI> getExistingOrRenamedResourceURIs() {
|
||||
ResourceSet resourceSet = descriptions.getResourceSet();
|
||||
if (resourceSet instanceof ResourceSetImpl)
|
||||
return ((ResourceSetImpl) resourceSet).getURIResourceMap().keySet();
|
||||
throw new IllegalStateException("ResourceSet is not a an instance of ResourceSetImpl.");
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource.containers
|
||||
|
||||
import com.google.common.annotations.Beta
|
||||
import java.util.Set
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.emf.ecore.EClass
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
|
||||
import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
|
||||
import org.eclipse.xtext.naming.QualifiedName
|
||||
import org.eclipse.xtext.resource.IContainer
|
||||
import org.eclipse.xtext.resource.impl.ChunkedResourceDescriptions
|
||||
import org.eclipse.xtext.resource.impl.LiveShadowedChunkedResourceDescriptions
|
||||
import org.eclipse.xtext.workspace.IProjectConfig
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.14
|
||||
*/
|
||||
@Beta
|
||||
@FinalFieldsConstructor
|
||||
class LiveShadowedChunkedContainer implements IContainer {
|
||||
|
||||
val LiveShadowedChunkedResourceDescriptions descriptions
|
||||
|
||||
val String containerName
|
||||
|
||||
IProjectConfig projectConfig
|
||||
|
||||
boolean isProjectConfigSet = false
|
||||
|
||||
|
||||
protected def getChunkedResourceDescriptions() {
|
||||
descriptions.globalDescriptions as ChunkedResourceDescriptions
|
||||
}
|
||||
|
||||
protected def getProjectConfig() {
|
||||
if (!isProjectConfigSet) {
|
||||
projectConfig = descriptions.workspaceConfig?.findProjectByName(containerName)
|
||||
isProjectConfigSet = true
|
||||
}
|
||||
return projectConfig
|
||||
}
|
||||
|
||||
protected def getChunk() {
|
||||
chunkedResourceDescriptions.getContainer(containerName) ?: new ResourceDescriptionsData(#[])
|
||||
}
|
||||
|
||||
protected def getContainedLocalDescriptions() {
|
||||
descriptions.localDescriptions.allResourceDescriptions.filter[URI.contained]
|
||||
}
|
||||
|
||||
protected def boolean isContained(URI uri) {
|
||||
chunk.getResourceDescription(uri) !== null || getProjectConfig?.findSourceFolderContaining(uri) !== null
|
||||
}
|
||||
|
||||
override getResourceDescription(URI uri) {
|
||||
if(uri.contained)
|
||||
descriptions.getResourceDescription(uri)
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override getResourceDescriptionCount() {
|
||||
resourceDescriptions.size
|
||||
}
|
||||
|
||||
override getResourceDescriptions() {
|
||||
val localURIs = existingOrRenamedResourceURIs
|
||||
return containedLocalDescriptions
|
||||
+ chunk.allResourceDescriptions.filter[!localURIs.contains(URI)]
|
||||
}
|
||||
|
||||
override hasResourceDescription(URI uri) {
|
||||
chunk.getResourceDescription(uri) !== null
|
||||
}
|
||||
|
||||
override getExportedObjects() {
|
||||
val localURIs = existingOrRenamedResourceURIs
|
||||
val flatten = containedLocalDescriptions.map[exportedObjects].flatten
|
||||
return flatten
|
||||
+ chunk.exportedObjects.filter[!localURIs.contains(EObjectURI.trimFragment)]
|
||||
}
|
||||
|
||||
override getExportedObjects(EClass type, QualifiedName name, boolean ignoreCase) {
|
||||
val localURIs = existingOrRenamedResourceURIs
|
||||
return containedLocalDescriptions.map[getExportedObjects(type, name, ignoreCase)].flatten
|
||||
+ chunk.getExportedObjects(type, name, ignoreCase).filter[!localURIs.contains(EObjectURI.trimFragment)]
|
||||
}
|
||||
|
||||
override getExportedObjectsByObject(EObject object) {
|
||||
val localURIs = existingOrRenamedResourceURIs
|
||||
return containedLocalDescriptions.map[getExportedObjectsByObject(object)].flatten
|
||||
+ chunk.getExportedObjectsByObject(object).filter[!localURIs.contains(EObjectURI.trimFragment)]
|
||||
}
|
||||
|
||||
override getExportedObjectsByType(EClass type) {
|
||||
val localURIs = existingOrRenamedResourceURIs
|
||||
return containedLocalDescriptions.map[getExportedObjectsByType(type)].flatten
|
||||
+ chunk.getExportedObjectsByType(type).filter[!localURIs.contains(EObjectURI.trimFragment)]
|
||||
}
|
||||
|
||||
override isEmpty() {
|
||||
containedLocalDescriptions.empty && chunk.empty
|
||||
}
|
||||
|
||||
def protected Set<URI> getExistingOrRenamedResourceURIs() {
|
||||
val resourceSet = descriptions.resourceSet
|
||||
if (resourceSet instanceof ResourceSetImpl)
|
||||
return resourceSet.URIResourceMap.keySet
|
||||
throw new IllegalStateException("ResourceSet is not a ResourceSetImpl")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.containers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.xtext.resource.IContainer;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.LiveShadowedChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ProjectDescription;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsBasedContainer;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
public class ProjectDescriptionBasedContainerManager implements IContainer.Manager {
|
||||
public boolean shouldUseProjectDescriptionBasedContainers(IResourceDescriptions resourceDescriptions) {
|
||||
ChunkedResourceDescriptions descriptions = getChunkedResourceDescriptions(resourceDescriptions);
|
||||
return (descriptions != null && descriptions.getResourceSet() != null
|
||||
&& ProjectDescription.findInEmfObject(descriptions.getResourceSet()) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IContainer getContainer(IResourceDescription desc, IResourceDescriptions resourceDescriptions) {
|
||||
ChunkedResourceDescriptions descriptions = getChunkedResourceDescriptions(resourceDescriptions);
|
||||
if (descriptions == null)
|
||||
throw new IllegalArgumentException("Expected " + ChunkedResourceDescriptions.class.getName());
|
||||
return createContainer(resourceDescriptions, descriptions,
|
||||
ProjectDescription.findInEmfObject(descriptions.getResourceSet()).getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IContainer> getVisibleContainers(IResourceDescription desc,
|
||||
IResourceDescriptions resourceDescriptions) {
|
||||
ChunkedResourceDescriptions descriptions = getChunkedResourceDescriptions(resourceDescriptions);
|
||||
if (descriptions == null)
|
||||
throw new IllegalArgumentException("Expected " + ChunkedResourceDescriptions.class.getName());
|
||||
ProjectDescription projectDescription = ProjectDescription.findInEmfObject(descriptions.getResourceSet());
|
||||
List<IContainer> allContainers = new ArrayList<>();
|
||||
allContainers.add(createContainer(resourceDescriptions, descriptions, projectDescription.getName()));
|
||||
for (String name : projectDescription.getDependencies())
|
||||
allContainers.add(createContainer(resourceDescriptions, descriptions, name));
|
||||
return allContainers;
|
||||
}
|
||||
|
||||
protected ChunkedResourceDescriptions getChunkedResourceDescriptions(IResourceDescriptions resourceDescriptions) {
|
||||
if (resourceDescriptions instanceof ChunkedResourceDescriptions)
|
||||
return (ChunkedResourceDescriptions) resourceDescriptions;
|
||||
if (resourceDescriptions instanceof LiveShadowedChunkedResourceDescriptions)
|
||||
return getChunkedResourceDescriptions(
|
||||
((LiveShadowedChunkedResourceDescriptions) resourceDescriptions).getGlobalDescriptions());
|
||||
return null;
|
||||
}
|
||||
|
||||
protected IContainer createContainer(IResourceDescriptions resourceDescriptions,
|
||||
ChunkedResourceDescriptions chunkedResourceDescriptions, String projectName) {
|
||||
if (resourceDescriptions instanceof LiveShadowedChunkedResourceDescriptions) {
|
||||
return new LiveShadowedChunkedContainer((LiveShadowedChunkedResourceDescriptions) resourceDescriptions,
|
||||
projectName);
|
||||
} else {
|
||||
ResourceDescriptionsData container = chunkedResourceDescriptions.getContainer(projectName);
|
||||
return new ResourceDescriptionsBasedContainer(
|
||||
container != null ? container : new ResourceDescriptionsData(Collections.emptySet()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2017 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource.containers
|
||||
|
||||
import com.google.common.annotations.Beta
|
||||
import org.eclipse.xtext.resource.IContainer
|
||||
import org.eclipse.xtext.resource.IResourceDescription
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions
|
||||
import org.eclipse.xtext.resource.impl.ChunkedResourceDescriptions
|
||||
import org.eclipse.xtext.resource.impl.LiveShadowedChunkedResourceDescriptions
|
||||
import org.eclipse.xtext.resource.impl.ProjectDescription
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsBasedContainer
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
class ProjectDescriptionBasedContainerManager implements IContainer.Manager {
|
||||
|
||||
def boolean shouldUseProjectDescriptionBasedContainers(IResourceDescriptions resourceDescriptions) {
|
||||
val chunkedResourceDescriptions = resourceDescriptions.chunkedResourceDescriptions
|
||||
return chunkedResourceDescriptions !== null
|
||||
&& chunkedResourceDescriptions.resourceSet !== null
|
||||
&& ProjectDescription.findInEmfObject(chunkedResourceDescriptions.resourceSet) !== null
|
||||
}
|
||||
|
||||
override getContainer(IResourceDescription desc, IResourceDescriptions resourceDescriptions) {
|
||||
val chunkedResourceDescriptions = resourceDescriptions.chunkedResourceDescriptions
|
||||
if (chunkedResourceDescriptions === null)
|
||||
throw new IllegalArgumentException("expected "+ChunkedResourceDescriptions.name)
|
||||
|
||||
val resourceSet = chunkedResourceDescriptions.resourceSet
|
||||
val projectDescription = ProjectDescription.findInEmfObject(resourceSet)
|
||||
val container = createContainer(resourceDescriptions, chunkedResourceDescriptions, projectDescription.name)
|
||||
return container
|
||||
}
|
||||
|
||||
override getVisibleContainers(IResourceDescription desc, IResourceDescriptions resourceDescriptions) {
|
||||
val chunkedResourceDescriptions = resourceDescriptions.chunkedResourceDescriptions
|
||||
if (chunkedResourceDescriptions === null)
|
||||
throw new IllegalArgumentException("expected "+ChunkedResourceDescriptions.name)
|
||||
val resourceSet = chunkedResourceDescriptions.resourceSet
|
||||
val projectDescription = ProjectDescription.findInEmfObject(resourceSet)
|
||||
val allContainers = <IContainer>newArrayList
|
||||
allContainers.add(createContainer(resourceDescriptions, chunkedResourceDescriptions, projectDescription.name))
|
||||
for (name : projectDescription.dependencies) {
|
||||
allContainers.add(createContainer(resourceDescriptions, chunkedResourceDescriptions, name))
|
||||
}
|
||||
return allContainers
|
||||
|
||||
}
|
||||
|
||||
protected def ChunkedResourceDescriptions getChunkedResourceDescriptions(IResourceDescriptions resourceDescriptions) {
|
||||
switch resourceDescriptions {
|
||||
ChunkedResourceDescriptions: resourceDescriptions
|
||||
LiveShadowedChunkedResourceDescriptions: resourceDescriptions.globalDescriptions.chunkedResourceDescriptions
|
||||
default: null
|
||||
}
|
||||
}
|
||||
|
||||
protected def createContainer(IResourceDescriptions resourceDescriptions, ChunkedResourceDescriptions chunkedResourceDescriptions, String projectName) {
|
||||
if(resourceDescriptions instanceof LiveShadowedChunkedResourceDescriptions)
|
||||
new LiveShadowedChunkedContainer(resourceDescriptions, projectName)
|
||||
else
|
||||
new ResourceDescriptionsBasedContainer(chunkedResourceDescriptions.getContainer(projectName) ?: new ResourceDescriptionsData(emptySet))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.impl;
|
||||
|
||||
import static com.google.common.collect.Iterables.*;
|
||||
import static org.eclipse.xtext.xbase.lib.IterableExtensions.*;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.ISelectable;
|
||||
import org.eclipse.xtext.resource.containers.ProjectDescriptionBasedContainerManager;
|
||||
import org.eclipse.xtext.resource.persistence.SerializableResourceDescription;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* A IResourceDescriptions implementation that holds its resource description in chunks, each identified by a string.
|
||||
* The strings represent units such as projects, source sets, and libraries.
|
||||
*
|
||||
* @see ProjectDescription
|
||||
* @see ProjectDescriptionBasedContainerManager
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
public class ChunkedResourceDescriptions extends AbstractCompoundSelectable
|
||||
implements IResourceDescriptions, Externalizable {
|
||||
|
||||
protected ConcurrentHashMap<String, ResourceDescriptionsData> chunk2resourceDescriptions = new ConcurrentHashMap<>();
|
||||
protected ResourceSet resourceSet;
|
||||
|
||||
public ChunkedResourceDescriptions() {
|
||||
}
|
||||
|
||||
public ChunkedResourceDescriptions(Map<String, ResourceDescriptionsData> initialData) {
|
||||
chunk2resourceDescriptions = new ConcurrentHashMap<>(initialData);
|
||||
}
|
||||
|
||||
public ChunkedResourceDescriptions(Map<String, ResourceDescriptionsData> initialData, ResourceSet resourceSet) {
|
||||
this(initialData);
|
||||
setResourceSet(resourceSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of the resource descriptions map and installs it with the given ResourceSet.
|
||||
*/
|
||||
public ChunkedResourceDescriptions createShallowCopyWith(ResourceSet resourceSet) {
|
||||
return new ChunkedResourceDescriptions(chunk2resourceDescriptions, resourceSet);
|
||||
}
|
||||
|
||||
public ResourceSet getResourceSet() {
|
||||
return resourceSet;
|
||||
}
|
||||
|
||||
protected void setResourceSet(ResourceSet resourceSet) {
|
||||
if (this.resourceSet != null)
|
||||
throw new IllegalStateException(
|
||||
"This " + getClass().getName() + " is already associated with a different resource set.");
|
||||
if (ChunkedResourceDescriptions.findInEmfObject(resourceSet) != null)
|
||||
throw new IllegalStateException(
|
||||
"There is already a different " + getClass().getName() + " installed in the given resource set.");
|
||||
this.resourceSet = resourceSet;
|
||||
attachToEmfObject(resourceSet);
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData setContainer(String name, ResourceDescriptionsData descriptions) {
|
||||
return chunk2resourceDescriptions.put(name, descriptions);
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData removeContainer(String name) {
|
||||
return chunk2resourceDescriptions.remove(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<? extends ISelectable> getSelectables() {
|
||||
return chunk2resourceDescriptions.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IResourceDescription> getAllResourceDescriptions() {
|
||||
return concat(map(chunk2resourceDescriptions.values(), it -> it.getAllResourceDescriptions()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceDescription getResourceDescription(URI uri) {
|
||||
for (ResourceDescriptionsData selectable : chunk2resourceDescriptions.values()) {
|
||||
IResourceDescription result = selectable.getResourceDescription(uri);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData getContainer(URI uri) {
|
||||
for (ResourceDescriptionsData container : chunk2resourceDescriptions.values()) {
|
||||
IResourceDescription description = container.getResourceDescription(uri);
|
||||
if (description != null)
|
||||
return container;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData getContainer(String containerHandle) {
|
||||
return chunk2resourceDescriptions.get(containerHandle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
int numChunks = in.readInt();
|
||||
for (int i = 0; i < numChunks; i++) {
|
||||
String chunkName = in.readUTF();
|
||||
int numDescriptions = in.readInt();
|
||||
List<IResourceDescription> descriptions = new ArrayList<IResourceDescription>(numDescriptions);
|
||||
for (int j = 0; j < numDescriptions; j++)
|
||||
descriptions.add((IResourceDescription) in.readObject());
|
||||
chunk2resourceDescriptions.put(chunkName, new ResourceDescriptionsData(descriptions));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
Map<String, ResourceDescriptionsData> copy = new HashMap<>(chunk2resourceDescriptions);
|
||||
out.writeInt(copy.entrySet().size());
|
||||
for (Entry<String, ResourceDescriptionsData> entry : copy.entrySet()) {
|
||||
out.writeUTF(entry.getKey());
|
||||
Iterable<Object> descriptions = map(entry.getValue().getAllResourceDescriptions(),
|
||||
d -> d instanceof Serializable ? d : SerializableResourceDescription.createCopy(d));
|
||||
out.writeInt(IterableExtensions.size(descriptions));
|
||||
for (Object d : descriptions)
|
||||
out.writeObject(d);
|
||||
}
|
||||
}
|
||||
|
||||
public static ChunkedResourceDescriptions findInEmfObject(Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters()) {
|
||||
if (adapter instanceof ChunkedResourceDescriptionsAdapter)
|
||||
return ((ChunkedResourceDescriptionsAdapter) adapter).get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ChunkedResourceDescriptions removeFromEmfObject(Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for (int i = 0; i < adapters.size(); i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof ChunkedResourceDescriptionsAdapter)
|
||||
return ((ChunkedResourceDescriptionsAdapter) emfObject.eAdapters().remove(i)).get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(Notifier emfObject) {
|
||||
ChunkedResourceDescriptions result = findInEmfObject(emfObject);
|
||||
if (result != null)
|
||||
throw new IllegalStateException(
|
||||
"The given EMF object already contains an adapter for ChunkedResourceDescriptions");
|
||||
ChunkedResourceDescriptionsAdapter adapter = new ChunkedResourceDescriptionsAdapter(this);
|
||||
emfObject.eAdapters().add(adapter);
|
||||
}
|
||||
|
||||
public static class ChunkedResourceDescriptionsAdapter extends AdapterImpl {
|
||||
private ChunkedResourceDescriptions element;
|
||||
|
||||
public ChunkedResourceDescriptionsAdapter(ChunkedResourceDescriptions element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public ChunkedResourceDescriptions get() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(Object object) {
|
||||
return object == ChunkedResourceDescriptions.class;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2016 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource.impl
|
||||
|
||||
import com.google.common.annotations.Beta
|
||||
import java.io.Externalizable
|
||||
import java.io.IOException
|
||||
import java.io.ObjectInput
|
||||
import java.io.ObjectOutput
|
||||
import java.io.Serializable
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import java.util.Map
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet
|
||||
import org.eclipse.xtext.resource.IResourceDescription
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions
|
||||
import org.eclipse.xtext.resource.containers.ProjectDescriptionBasedContainerManager
|
||||
import org.eclipse.xtext.resource.persistence.SerializableResourceDescription
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable
|
||||
|
||||
/**
|
||||
* A IResourceDescriptions implementation that holds its resource description in chunks, each identified by a string.
|
||||
* The strings represent units such as projects, source sets, and libraries.
|
||||
*
|
||||
* @see ProjectDescription
|
||||
* @see ProjectDescriptionBasedContainerManager
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
@EmfAdaptable class ChunkedResourceDescriptions extends AbstractCompoundSelectable implements IResourceDescriptions, Externalizable {
|
||||
|
||||
protected ConcurrentHashMap<String, ResourceDescriptionsData> chunk2resourceDescriptions = new ConcurrentHashMap;
|
||||
|
||||
protected ResourceSet resourceSet
|
||||
|
||||
new() {}
|
||||
|
||||
new(Map<String,ResourceDescriptionsData> initialData) {
|
||||
this.chunk2resourceDescriptions = new ConcurrentHashMap(initialData)
|
||||
}
|
||||
|
||||
new(Map<String,ResourceDescriptionsData> initialData, ResourceSet resourceSet) {
|
||||
this(initialData)
|
||||
setResourceSet(resourceSet)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of the resource descriptions map and installs it with the given ResourceSet.
|
||||
*/
|
||||
def ChunkedResourceDescriptions createShallowCopyWith(ResourceSet resourceSet) {
|
||||
return new ChunkedResourceDescriptions(chunk2resourceDescriptions, resourceSet)
|
||||
}
|
||||
|
||||
def ResourceSet getResourceSet() {
|
||||
resourceSet
|
||||
}
|
||||
|
||||
protected def void setResourceSet(ResourceSet resourceSet) {
|
||||
if (this.resourceSet !== null) {
|
||||
throw new IllegalStateException("This "+class.name+" is already associated with a different resource set.")
|
||||
}
|
||||
val index = findInEmfObject(resourceSet)
|
||||
if (index !== null) {
|
||||
throw new IllegalStateException("There is already a different "+class.name+" installed in the given resource set.")
|
||||
}
|
||||
this.resourceSet = resourceSet
|
||||
attachToEmfObject(resourceSet)
|
||||
}
|
||||
|
||||
def ResourceDescriptionsData setContainer(String name, ResourceDescriptionsData descriptions) {
|
||||
return chunk2resourceDescriptions.put(name, descriptions)
|
||||
}
|
||||
|
||||
def ResourceDescriptionsData removeContainer(String name) {
|
||||
return chunk2resourceDescriptions.remove(name)
|
||||
}
|
||||
|
||||
override protected getSelectables() {
|
||||
return chunk2resourceDescriptions.values
|
||||
}
|
||||
|
||||
override getAllResourceDescriptions() {
|
||||
chunk2resourceDescriptions.values.map[it.getAllResourceDescriptions()].flatten
|
||||
}
|
||||
|
||||
override getResourceDescription(URI uri) {
|
||||
for (selectable : chunk2resourceDescriptions.values) {
|
||||
val result = selectable.getResourceDescription(uri)
|
||||
if (result !== null)
|
||||
return result
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
def ResourceDescriptionsData getContainer(URI uri) {
|
||||
for (container : chunk2resourceDescriptions.values) {
|
||||
val result = container.getResourceDescription(uri)
|
||||
if (result !== null)
|
||||
return container
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
def ResourceDescriptionsData getContainer(String containerHandle) {
|
||||
return chunk2resourceDescriptions.get(containerHandle)
|
||||
}
|
||||
|
||||
override readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
val numChunks = in.readInt
|
||||
for(i: 0..<numChunks) {
|
||||
val chunkName = in.readUTF
|
||||
val numDescriptions = in.readInt
|
||||
val descriptions = new ArrayList(numDescriptions)
|
||||
for(j: 0..<numDescriptions)
|
||||
descriptions.add(in.readObject as IResourceDescription)
|
||||
chunk2resourceDescriptions.put(chunkName, new ResourceDescriptionsData(descriptions))
|
||||
}
|
||||
}
|
||||
|
||||
override writeExternal(ObjectOutput out) throws IOException {
|
||||
val copy = new HashMap(chunk2resourceDescriptions)
|
||||
out.writeInt(copy.entrySet.size)
|
||||
copy.entrySet.forEach[
|
||||
out.writeUTF(key)
|
||||
val descriptions = value.allResourceDescriptions.map[
|
||||
if(it instanceof Serializable)
|
||||
it
|
||||
else
|
||||
SerializableResourceDescription.createCopy(it)
|
||||
]
|
||||
out.writeInt(descriptions.size)
|
||||
descriptions.forEach[
|
||||
out.writeObject(it)
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Copyright (c) 2011, 2020 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.impl;
|
||||
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtext.EcoreUtil2;
|
||||
import org.eclipse.xtext.workspace.IProjectConfig;
|
||||
import org.eclipse.xtext.workspace.IProjectConfigProvider;
|
||||
import org.eclipse.xtext.workspace.IWorkspaceConfig;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* @author Jan Koehnlein - Initial contribution and API
|
||||
* @since 2.14
|
||||
*/
|
||||
public class LiveShadowedChunkedResourceDescriptions extends LiveShadowedResourceDescriptions {
|
||||
@Inject(optional = true)
|
||||
private IProjectConfigProvider projectConfigProvider;
|
||||
|
||||
private IWorkspaceConfig workspaceConfig;
|
||||
|
||||
@Override
|
||||
public void setContext(Notifier ctx) {
|
||||
ResourceSetBasedResourceDescriptions localDescriptions = (ResourceSetBasedResourceDescriptions) getLocalDescriptions();
|
||||
localDescriptions.setContext(ctx);
|
||||
localDescriptions.setData(null);
|
||||
ResourceSet resourceSet = EcoreUtil2.getResourceSet(ctx);
|
||||
setGlobalDescriptions(ChunkedResourceDescriptions.findInEmfObject(resourceSet));
|
||||
if (projectConfigProvider == null) {
|
||||
workspaceConfig = null;
|
||||
} else {
|
||||
IProjectConfig projectConfig = projectConfigProvider.getProjectConfig(resourceSet);
|
||||
workspaceConfig = projectConfig == null ? null : projectConfig.getWorkspaceConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public IWorkspaceConfig getWorkspaceConfig() {
|
||||
return workspaceConfig;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2011, 2017 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.impl
|
||||
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.emf.common.notify.Notifier
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.workspace.IProjectConfigProvider
|
||||
import org.eclipse.xtext.workspace.IWorkspaceConfig
|
||||
|
||||
import static extension org.eclipse.xtext.EcoreUtil2.*
|
||||
|
||||
/**
|
||||
* @author Jan Koehnlein - Initial contribution and API
|
||||
* @since 2.14
|
||||
*/
|
||||
class LiveShadowedChunkedResourceDescriptions extends LiveShadowedResourceDescriptions {
|
||||
|
||||
@Inject(optional = true) IProjectConfigProvider projectConfigProvider
|
||||
|
||||
@Accessors(PUBLIC_GETTER) IWorkspaceConfig workspaceConfig
|
||||
|
||||
override void setContext(Notifier ctx) {
|
||||
(localDescriptions as ResourceSetBasedResourceDescriptions) => [
|
||||
context = ctx
|
||||
data = null
|
||||
]
|
||||
val resourceSet = ctx.resourceSet
|
||||
globalDescriptions = ChunkedResourceDescriptions.findInEmfObject(resourceSet)
|
||||
workspaceConfig = projectConfigProvider?.getProjectConfig(resourceSet)?.workspaceConfig
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
public class ProjectDescription {
|
||||
|
||||
/**
|
||||
* A unique name for this project
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* list of logical names of upstream dependencies
|
||||
*/
|
||||
private List<String> dependencies = new ArrayList<>();
|
||||
|
||||
public static ProjectDescription findInEmfObject(Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters()) {
|
||||
if (adapter instanceof ProjectDescriptionAdapter)
|
||||
return ((ProjectDescriptionAdapter) adapter).get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ProjectDescription removeFromEmfObject(Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for (int i = 0; i < adapters.size(); i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof ProjectDescriptionAdapter)
|
||||
return ((ProjectDescriptionAdapter) emfObject.eAdapters().remove(i)).get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(Notifier emfObject) {
|
||||
if (findInEmfObject(emfObject) != null)
|
||||
throw new IllegalStateException("The given EMF object already contains an adapter for ProjectDescription");
|
||||
emfObject.eAdapters().add(new ProjectDescriptionAdapter(this));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<String> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public void setDependencies(List<String> dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this).add("name", name).add("dependencies", dependencies).toString();
|
||||
}
|
||||
|
||||
public static class ProjectDescriptionAdapter extends AdapterImpl {
|
||||
private ProjectDescription element;
|
||||
|
||||
public ProjectDescriptionAdapter(ProjectDescription element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public ProjectDescription get() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(Object object) {
|
||||
return object == ProjectDescription.class;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2017 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.resource.impl
|
||||
|
||||
import java.util.List
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable
|
||||
import com.google.common.annotations.Beta
|
||||
import org.eclipse.xtend.lib.annotations.ToString
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
@ToString
|
||||
@EmfAdaptable class ProjectDescription {
|
||||
|
||||
/**
|
||||
* A unique name for this project
|
||||
*/
|
||||
@Accessors String name
|
||||
|
||||
/**
|
||||
* list of logical names of upstream dependencies
|
||||
*/
|
||||
@Accessors List<String> dependencies = newArrayList
|
||||
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.xtext;
|
||||
|
||||
import static com.google.common.collect.Iterables.*;
|
||||
import static org.eclipse.xtext.xbase.lib.IterableExtensions.*;
|
||||
import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.EReference;
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil;
|
||||
import org.eclipse.xtext.AbstractElement;
|
||||
import org.eclipse.xtext.AbstractRule;
|
||||
import org.eclipse.xtext.CompoundElement;
|
||||
import org.eclipse.xtext.Condition;
|
||||
import org.eclipse.xtext.EnumRule;
|
||||
import org.eclipse.xtext.Grammar;
|
||||
import org.eclipse.xtext.GrammarUtil;
|
||||
import org.eclipse.xtext.Group;
|
||||
import org.eclipse.xtext.Parameter;
|
||||
import org.eclipse.xtext.ParserRule;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
import org.eclipse.xtext.TerminalRule;
|
||||
import org.eclipse.xtext.TypeRef;
|
||||
import org.eclipse.xtext.XtextPackage;
|
||||
import org.eclipse.xtext.xbase.lib.ListExtensions;
|
||||
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Sebastian Zarnekow - Initial contribution and API
|
||||
*/
|
||||
public class FlattenedGrammarAccess {
|
||||
private final Grammar flattenedGrammar;
|
||||
|
||||
public FlattenedGrammarAccess(RuleNames names, RuleFilter filter) {
|
||||
Grammar grammar = names.getContextGrammar();
|
||||
Grammar flattenedGrammar = copy(grammar);
|
||||
flattenedGrammar.setName(grammar.getName());
|
||||
Map<RuleWithParameterValues, AbstractRule> origToCopy = new LinkedHashMap<>();
|
||||
List<AbstractRule> copies = copyRuleStubs(names, origToCopy, filter.getRules(grammar),
|
||||
filter.isDiscardRuleTypeRef());
|
||||
addAll(flattenedGrammar.getRules(), copies);
|
||||
Multimap<TerminalRule, AbstractRule> calledFrom = copyRuleBodies(copies, origToCopy);
|
||||
setHiddenTokens(flattenedGrammar, grammar, origToCopy);
|
||||
markAsFragment(calledFrom);
|
||||
if (filter.isDiscardUnreachableRules()) {
|
||||
Set<AbstractRule> usedRules = new HashSet<>();
|
||||
if (!filter.isDiscardTerminalRules())
|
||||
usedRules.addAll(GrammarUtil.allTerminalRules(flattenedGrammar));
|
||||
UsedRulesFinder finder = new UsedRulesFinder(usedRules);
|
||||
finder.compute(flattenedGrammar);
|
||||
flattenedGrammar.getRules().retainAll(usedRules);
|
||||
}
|
||||
this.flattenedGrammar = flattenedGrammar;
|
||||
new OriginalGrammar(grammar).attachToEmfObject(flattenedGrammar);
|
||||
}
|
||||
|
||||
private void setHiddenTokens(Grammar copy, Grammar orig, Map<RuleWithParameterValues, AbstractRule> origToCopy) {
|
||||
if (orig == null) {
|
||||
copy.setDefinesHiddenTokens(true);
|
||||
return;
|
||||
}
|
||||
if (!orig.isDefinesHiddenTokens()) {
|
||||
setHiddenTokens(copy, head(orig.getUsedGrammars()), origToCopy);
|
||||
return;
|
||||
}
|
||||
copy.setDefinesHiddenTokens(true);
|
||||
addAll(copy.getHiddenTokens(), ListExtensions.map(orig.getHiddenTokens(),
|
||||
hidden -> origToCopy.get(new RuleWithParameterValues(hidden))));
|
||||
}
|
||||
|
||||
private void markAsFragment(Multimap<TerminalRule, AbstractRule> calledFrom) {
|
||||
FluentIterable.from(calledFrom.keySet()).filter(it -> !it.isFragment())
|
||||
.filter(it -> allAreTerminalRules(calledFrom.get(it)))
|
||||
.filter(it -> !((Grammar) it.eContainer()).getHiddenTokens().contains(it))
|
||||
.forEach(it -> it.setFragment(true));
|
||||
}
|
||||
|
||||
private Multimap<TerminalRule, AbstractRule> copyRuleBodies(List<AbstractRule> copies,
|
||||
Map<RuleWithParameterValues, AbstractRule> origToCopy) {
|
||||
HashMultimap<TerminalRule, AbstractRule> calledFrom = HashMultimap.create();
|
||||
for (AbstractRule copy : copies) {
|
||||
AbstractRule orig = RuleWithParameterValues.getOriginalRule(copy);
|
||||
Set<Parameter> paramValues = RuleWithParameterValues.getParamValues(copy);
|
||||
@SuppressWarnings("serial")
|
||||
EcoreUtil.Copier copier = new EcoreUtil.Copier() {
|
||||
@Override
|
||||
protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) {
|
||||
if (XtextPackage.Literals.RULE_CALL__RULE == eReference) {
|
||||
RuleCall origRuleCall = (RuleCall) eObject;
|
||||
RuleCall copyRuleCall = (RuleCall) copyEObject;
|
||||
AbstractRule calledCopy = origToCopy.get(new RuleWithParameterValues(origRuleCall.getRule(),
|
||||
getParameterConfig(origRuleCall, copyRuleCall)));
|
||||
copyRuleCall.setRule(calledCopy);
|
||||
if (calledCopy instanceof TerminalRule)
|
||||
calledFrom.put((TerminalRule) calledCopy, copy);
|
||||
} else {
|
||||
super.copyReference(eReference, eObject, copyEObject);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Parameter> getParameterConfig(RuleCall origRuleCall, RuleCall copyRuleCall) {
|
||||
if (origRuleCall.getArguments().isEmpty())
|
||||
return Collections.emptySet();
|
||||
return toSet(map(filter(origRuleCall.getArguments(), it -> evaluate(it.getValue())),
|
||||
it -> it.getParameter()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
|
||||
if (XtextPackage.Literals.RULE_CALL__ARGUMENTS == eReference
|
||||
|| XtextPackage.Literals.GROUP__GUARD_CONDITION == eReference)
|
||||
return;
|
||||
super.copyContainment(eReference, eObject, copyEObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EObject copy(EObject eObject) {
|
||||
if (eObject instanceof Group && ((Group) eObject).getGuardCondition() != null
|
||||
&& !evaluate(((Group) eObject).getGuardCondition()))
|
||||
return null;
|
||||
EObject result = super.copy(eObject);
|
||||
if (result instanceof CompoundElement) {
|
||||
CompoundElement compoundElement = (CompoundElement) result;
|
||||
List<AbstractElement> elements = compoundElement.getElements();
|
||||
if (elements.size() == 1) {
|
||||
if (!compoundElement.isFirstSetPredicated() && !compoundElement.isPredicated()) {
|
||||
AbstractElement firstElement = elements.get(0);
|
||||
mergeCardinalities(firstElement, compoundElement);
|
||||
mergePredicates(firstElement, compoundElement);
|
||||
return firstElement;
|
||||
} else {
|
||||
AbstractElement firstElement = elements.get(0);
|
||||
mergePredicates(compoundElement, firstElement);
|
||||
firstElement.setFirstSetPredicated(false);
|
||||
firstElement.setPredicated(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((eObject instanceof AbstractElement)) {
|
||||
AbstractElement abstractElement = (AbstractElement) eObject;
|
||||
if (!abstractElement.eClass().equals(result.eClass())) {
|
||||
throw new IllegalStateException("copy is: \'" + result.eClass().getName()
|
||||
+ "\' but original was: \'" + abstractElement.eClass().getName() + "\'");
|
||||
}
|
||||
new OriginalElement(abstractElement).attachToEmfObject(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void mergePredicates(AbstractElement into, AbstractElement from) {
|
||||
if (from.isPredicated()) {
|
||||
into.setPredicated(true);
|
||||
into.setFirstSetPredicated(false);
|
||||
} else {
|
||||
if (!into.isPredicated() && from.isFirstSetPredicated())
|
||||
into.setFirstSetPredicated(true);
|
||||
}
|
||||
}
|
||||
|
||||
void mergeCardinalities(AbstractElement into, AbstractElement from) {
|
||||
String c1 = into.getCardinality();
|
||||
String c2 = from.getCardinality();
|
||||
String resultCardinality = c1 == null ? c2 : c1;
|
||||
if (("*".equals(c1) || "*".equals(c2)) || ("+".equals(c1) && "?".equals(c2))
|
||||
|| ("?".equals(c1) && "+".equals(c2)))
|
||||
resultCardinality = "*";
|
||||
into.setCardinality(resultCardinality);
|
||||
}
|
||||
|
||||
boolean evaluate(final Condition condition) {
|
||||
return new ConditionEvaluator(paramValues).evaluate(condition);
|
||||
}
|
||||
};
|
||||
AbstractElement copiedBody = (AbstractElement) copier.copy(orig.getAlternatives());
|
||||
copier.copyReferences();
|
||||
copy.setAlternatives(copiedBody);
|
||||
if (orig instanceof ParserRule) {
|
||||
ParserRule castedCopy = ((ParserRule) copy);
|
||||
if (((ParserRule) orig).isDefinesHiddenTokens()) {
|
||||
castedCopy.setDefinesHiddenTokens(true);
|
||||
for (AbstractRule rule : ((ParserRule) orig).getHiddenTokens()) {
|
||||
AbstractRule copiedTerminalRule = origToCopy.get(new RuleWithParameterValues(rule));
|
||||
castedCopy.getHiddenTokens().add(copiedTerminalRule);
|
||||
calledFrom.put((TerminalRule) copiedTerminalRule, castedCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return calledFrom;
|
||||
}
|
||||
|
||||
private TypeRef copyTypeRef(TypeRef ref) {
|
||||
if (ref == null)
|
||||
return null;
|
||||
TypeRef copy = copy(ref);
|
||||
copy.setClassifier(ref.getClassifier());
|
||||
return copy;
|
||||
}
|
||||
|
||||
private List<AbstractRule> copyRuleStubs(RuleNames names, Map<RuleWithParameterValues, AbstractRule> origToCopy,
|
||||
List<AbstractRule> rulesToCopy, boolean discardTypeRef) {
|
||||
List<AbstractRule> result = new ArrayList<>();
|
||||
for (AbstractRule rule : rulesToCopy) {
|
||||
String ruleName = names.getAntlrRuleName(rule);
|
||||
if (rule instanceof ParserRule) {
|
||||
List<Parameter> params = ((ParserRule) rule).getParameters();
|
||||
if (params.isEmpty()) {
|
||||
ParserRule copy = copy((ParserRule) rule);
|
||||
copy.setName(ruleName);
|
||||
copy.setFragment(((ParserRule) rule).isFragment());
|
||||
copy.setWildcard(((ParserRule) rule).isWildcard());
|
||||
if (!discardTypeRef)
|
||||
copy.setType(copyTypeRef(((ParserRule) rule).getType()));
|
||||
attachTo(copy, rule, origToCopy);
|
||||
result.add(copy);
|
||||
} else {
|
||||
forEach(Sets.powerSet(ImmutableSet.copyOf(params)), (parameterConfig, i) -> {
|
||||
RuleWithParameterValues parameterValues = new RuleWithParameterValues(rule, parameterConfig);
|
||||
ParserRule copy = copy((ParserRule) rule);
|
||||
copy.setName(names.getAntlrRuleName(rule, i.intValue()));
|
||||
copy.setFragment(((ParserRule) rule).isFragment());
|
||||
copy.setWildcard(((ParserRule) rule).isWildcard());
|
||||
if (!discardTypeRef)
|
||||
copy.setType(copyTypeRef(((ParserRule) rule).getType()));
|
||||
origToCopy.put(parameterValues, copy);
|
||||
parameterValues.attachToEmfObject(copy);
|
||||
result.add(copy);
|
||||
});
|
||||
}
|
||||
} else if (rule instanceof TerminalRule) {
|
||||
TerminalRule orig = ((TerminalRule) rule);
|
||||
TerminalRule copy = copy(orig);
|
||||
copy.setName(ruleName);
|
||||
copy.setFragment(orig.isFragment());
|
||||
attachTo(copy, orig, origToCopy);
|
||||
result.add(copy);
|
||||
} else if (rule instanceof EnumRule) {
|
||||
EnumRule copy = copy((EnumRule) rule);
|
||||
copy.setName(ruleName);
|
||||
attachTo(copy, rule, origToCopy);
|
||||
result.add(copy);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private AbstractRule attachTo(AbstractRule copy, AbstractRule orig,
|
||||
Map<RuleWithParameterValues, AbstractRule> origToCopy) {
|
||||
RuleWithParameterValues parameterValues = new RuleWithParameterValues(orig);
|
||||
parameterValues.attachToEmfObject(copy);
|
||||
return origToCopy.put(parameterValues, copy);
|
||||
}
|
||||
|
||||
private boolean allAreTerminalRules(Collection<AbstractRule> callers) {
|
||||
return forall(callers, it -> it instanceof TerminalRule);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends EObject> T copy(final T t) {
|
||||
return (T) EcoreUtil.create(t.eClass());
|
||||
}
|
||||
|
||||
public static FlattenedGrammarAccess findInEmfObject(Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters()) {
|
||||
if (adapter instanceof FlattenedGrammarAccessAdapter)
|
||||
return ((FlattenedGrammarAccessAdapter) adapter).get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FlattenedGrammarAccess removeFromEmfObject(Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for (int i = 0; i < adapters.size(); i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof FlattenedGrammarAccessAdapter)
|
||||
return ((FlattenedGrammarAccessAdapter) emfObject.eAdapters().remove(i)).get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(Notifier emfObject) {
|
||||
if (findInEmfObject(emfObject) != null)
|
||||
throw new IllegalStateException(
|
||||
"The given EMF object already contains an adapter for FlattenedGrammarAccess");
|
||||
emfObject.eAdapters().add(new FlattenedGrammarAccess.FlattenedGrammarAccessAdapter(this));
|
||||
}
|
||||
|
||||
public Grammar getFlattenedGrammar() {
|
||||
return flattenedGrammar;
|
||||
}
|
||||
|
||||
public static class FlattenedGrammarAccessAdapter extends AdapterImpl {
|
||||
private FlattenedGrammarAccess element;
|
||||
|
||||
public FlattenedGrammarAccessAdapter(FlattenedGrammarAccess element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public FlattenedGrammarAccess get() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(Object object) {
|
||||
return object == FlattenedGrammarAccess.class;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,306 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.xtext
|
||||
|
||||
import com.google.common.collect.HashMultimap
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import com.google.common.collect.Maps
|
||||
import com.google.common.collect.Multimap
|
||||
import com.google.common.collect.Sets
|
||||
import java.util.Collection
|
||||
import java.util.Collections
|
||||
import java.util.List
|
||||
import java.util.Map
|
||||
import java.util.Set
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.EReference
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.AbstractElement
|
||||
import org.eclipse.xtext.AbstractRule
|
||||
import org.eclipse.xtext.CompoundElement
|
||||
import org.eclipse.xtext.Condition
|
||||
import org.eclipse.xtext.EnumRule
|
||||
import org.eclipse.xtext.Grammar
|
||||
import org.eclipse.xtext.GrammarUtil
|
||||
import org.eclipse.xtext.Group
|
||||
import org.eclipse.xtext.Parameter
|
||||
import org.eclipse.xtext.ParserRule
|
||||
import org.eclipse.xtext.RuleCall
|
||||
import org.eclipse.xtext.TerminalRule
|
||||
import org.eclipse.xtext.XtextPackage
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable
|
||||
|
||||
import static extension org.eclipse.xtext.xtext.RuleWithParameterValues.*
|
||||
import org.eclipse.xtext.TypeRef
|
||||
|
||||
/**
|
||||
* @author Sebastian Zarnekow - Initial contribution and API
|
||||
*/
|
||||
@EmfAdaptable
|
||||
class FlattenedGrammarAccess {
|
||||
|
||||
@Accessors
|
||||
val Grammar flattenedGrammar
|
||||
|
||||
new(RuleNames names, RuleFilter filter) {
|
||||
val grammar = names.contextGrammar
|
||||
var flattenedGrammar = copy(grammar)
|
||||
flattenedGrammar.name = grammar.name
|
||||
var origToCopy = Maps.newLinkedHashMap()
|
||||
val copies = copyRuleStubs(names, origToCopy, filter.getRules(grammar), filter.discardRuleTypeRef)
|
||||
flattenedGrammar.rules += copies
|
||||
var calledFrom = copyRuleBodies(copies, origToCopy)
|
||||
flattenedGrammar.setHiddenTokens(grammar, origToCopy)
|
||||
markAsFragment(calledFrom)
|
||||
if (filter.isDiscardUnreachableRules()) {
|
||||
var Set<AbstractRule> usedRules = newHashSet()
|
||||
if (!filter.isDiscardTerminalRules()) {
|
||||
usedRules.addAll(GrammarUtil.allTerminalRules(flattenedGrammar))
|
||||
}
|
||||
var UsedRulesFinder finder = new UsedRulesFinder(usedRules)
|
||||
finder.compute(flattenedGrammar)
|
||||
flattenedGrammar.rules.retainAll(usedRules)
|
||||
}
|
||||
this.flattenedGrammar = flattenedGrammar
|
||||
new OriginalGrammar(grammar).attachToEmfObject(flattenedGrammar)
|
||||
}
|
||||
|
||||
def private void setHiddenTokens(
|
||||
Grammar copy,
|
||||
Grammar orig,
|
||||
Map<RuleWithParameterValues, AbstractRule> origToCopy
|
||||
) {
|
||||
if (orig === null) {
|
||||
copy.definesHiddenTokens = true
|
||||
} else if (!orig.isDefinesHiddenTokens) {
|
||||
copy.setHiddenTokens(orig.usedGrammars.head, origToCopy)
|
||||
} else {
|
||||
copy.definesHiddenTokens = true
|
||||
copy.hiddenTokens += orig.hiddenTokens.map [ hidden |
|
||||
origToCopy.get(new RuleWithParameterValues(hidden))
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
def private void markAsFragment(Multimap<TerminalRule, AbstractRule> calledFrom) {
|
||||
calledFrom.keySet.filter [
|
||||
!isFragment
|
||||
].filter [
|
||||
allAreTerminalRules(calledFrom.get(it))
|
||||
].filter [
|
||||
!(it.eContainer as Grammar).hiddenTokens.contains(it)
|
||||
].forEach [
|
||||
fragment = true
|
||||
]
|
||||
}
|
||||
|
||||
def private Multimap<TerminalRule, AbstractRule> copyRuleBodies(
|
||||
List<AbstractRule> copies,
|
||||
Map<RuleWithParameterValues, AbstractRule> origToCopy
|
||||
) {
|
||||
val calledFrom = HashMultimap.create()
|
||||
for (copy : copies) {
|
||||
var orig = copy.originalRule
|
||||
val paramValues = copy.paramValues
|
||||
var EcoreUtil.Copier copier = new EcoreUtil.Copier() {
|
||||
override protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) {
|
||||
if (eReference === XtextPackage.Literals.RULE_CALL__RULE) {
|
||||
var origRuleCall = eObject as RuleCall
|
||||
var copyRuleCall = copyEObject as RuleCall
|
||||
var calledCopy = origToCopy.get(
|
||||
new RuleWithParameterValues(origRuleCall.getRule(),
|
||||
getParameterConfig(origRuleCall, copyRuleCall)))
|
||||
copyRuleCall.rule = calledCopy
|
||||
if (calledCopy instanceof TerminalRule) {
|
||||
calledFrom.put(calledCopy, copy)
|
||||
}
|
||||
} else {
|
||||
super.copyReference(eReference, eObject, copyEObject)
|
||||
}
|
||||
}
|
||||
|
||||
def private Set<Parameter> getParameterConfig(RuleCall origRuleCall, RuleCall copyRuleCall) {
|
||||
if (origRuleCall.getArguments().isEmpty())
|
||||
return Collections.emptySet()
|
||||
var result = origRuleCall.arguments.filter[value.evaluate].map[parameter].toSet
|
||||
return result
|
||||
}
|
||||
|
||||
override protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
|
||||
switch (eReference) {
|
||||
case XtextPackage.Literals.RULE_CALL__ARGUMENTS,
|
||||
case XtextPackage.Literals.GROUP__GUARD_CONDITION: return
|
||||
default: super.copyContainment(eReference, eObject, copyEObject)
|
||||
}
|
||||
}
|
||||
|
||||
override EObject copy(EObject eObject) {
|
||||
if (eObject instanceof Group) {
|
||||
var Group group = eObject
|
||||
if (group.getGuardCondition() !== null) {
|
||||
if (!evaluate(group.getGuardCondition())) {
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
var result = super.copy(eObject)
|
||||
if (result instanceof CompoundElement) {
|
||||
var List<AbstractElement> elements = result.getElements()
|
||||
if (elements.size() === 1) {
|
||||
if (!result.isFirstSetPredicated && !result.isPredicated) {
|
||||
var element = elements.get(0)
|
||||
element.mergeCardinalities(result)
|
||||
element.mergePredicates(result)
|
||||
return element
|
||||
} else {
|
||||
var element = elements.get(0)
|
||||
result.mergePredicates(element)
|
||||
element.firstSetPredicated = false
|
||||
element.predicated = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eObject instanceof AbstractElement) {
|
||||
var original = new OriginalElement(eObject)
|
||||
if (eObject.eClass != result.eClass) {
|
||||
throw new IllegalStateException(
|
||||
"copy is: '" + result.eClass.name + "' but original was: '" + eObject.eClass.name + "'")
|
||||
}
|
||||
original.attachToEmfObject(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def private void mergePredicates(AbstractElement into, AbstractElement from) {
|
||||
if (from.isPredicated()) {
|
||||
into.setPredicated(true)
|
||||
into.setFirstSetPredicated(false)
|
||||
} else if (!into.isPredicated() && from.isFirstSetPredicated()) {
|
||||
into.setFirstSetPredicated(true)
|
||||
}
|
||||
}
|
||||
|
||||
def private void mergeCardinalities(AbstractElement into, AbstractElement from) {
|
||||
var c1 = into.cardinality
|
||||
var c2 = from.cardinality
|
||||
into.cardinality = switch c1 {
|
||||
case c1 == '*' || c2 == '*',
|
||||
case c1 == '+' && c2 == '?',
|
||||
case c1 == '?' && c2 == '+': '*'
|
||||
case null: c2
|
||||
default: c1
|
||||
}
|
||||
}
|
||||
|
||||
def private boolean evaluate(Condition condition) {
|
||||
var result = new ConditionEvaluator(paramValues).evaluate(condition)
|
||||
return result
|
||||
}
|
||||
}
|
||||
var copiedBody = copier.copy(orig.alternatives) as AbstractElement
|
||||
copier.copyReferences()
|
||||
copy.alternatives = copiedBody
|
||||
if (orig instanceof ParserRule) {
|
||||
var ParserRule castedCopy = copy as ParserRule
|
||||
if (orig.isDefinesHiddenTokens) {
|
||||
castedCopy.definesHiddenTokens = true
|
||||
for (AbstractRule rule : orig.hiddenTokens) {
|
||||
val copiedTerminalRule = origToCopy.get(new RuleWithParameterValues(rule))
|
||||
castedCopy.hiddenTokens += copiedTerminalRule
|
||||
calledFrom.put(copiedTerminalRule as TerminalRule, castedCopy)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return calledFrom
|
||||
}
|
||||
|
||||
def private copyTypeRef(TypeRef ref) {
|
||||
if (ref === null)
|
||||
return null
|
||||
val copy = copy(ref)
|
||||
copy.classifier = ref.classifier
|
||||
return copy
|
||||
}
|
||||
|
||||
def private copyRuleStubs(
|
||||
RuleNames names,
|
||||
Map<RuleWithParameterValues, AbstractRule> origToCopy,
|
||||
List<AbstractRule> rulesToCopy,
|
||||
boolean discardTypeRef
|
||||
) {
|
||||
val result = <AbstractRule>newArrayList
|
||||
for (AbstractRule rule : rulesToCopy) {
|
||||
var String ruleName = names.getAntlrRuleName(rule)
|
||||
switch rule {
|
||||
ParserRule: {
|
||||
var List<Parameter> params = rule.parameters
|
||||
if (params.isEmpty) {
|
||||
var copy = copy(rule)
|
||||
copy.name = ruleName
|
||||
copy.fragment = rule.isFragment
|
||||
copy.wildcard = rule.isWildcard
|
||||
if (!discardTypeRef) {
|
||||
copy.type = copyTypeRef(rule.type)
|
||||
}
|
||||
copy.attachTo(rule, origToCopy)
|
||||
result += copy
|
||||
} else {
|
||||
Sets.powerSet(ImmutableSet.copyOf(params)).forEach [ parameterConfig, i |
|
||||
var parameterValues = new RuleWithParameterValues(rule, parameterConfig)
|
||||
var copy = copy(rule)
|
||||
copy.name = names.getAntlrRuleName(rule, i)
|
||||
copy.fragment = rule.isFragment
|
||||
copy.wildcard = rule.isWildcard
|
||||
if (!discardTypeRef) {
|
||||
copy.type = copyTypeRef(rule.type)
|
||||
}
|
||||
origToCopy.put(parameterValues, copy)
|
||||
parameterValues.attachToEmfObject(copy)
|
||||
result += copy
|
||||
]
|
||||
}
|
||||
}
|
||||
TerminalRule: {
|
||||
var orig = rule
|
||||
var copy = copy(orig)
|
||||
copy.name = ruleName
|
||||
copy.fragment = orig.isFragment
|
||||
copy.attachTo(orig, origToCopy)
|
||||
result += copy
|
||||
}
|
||||
EnumRule: {
|
||||
var copy = copy(rule)
|
||||
copy.name = ruleName
|
||||
copy.attachTo(rule, origToCopy)
|
||||
result += copy
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def private attachTo(AbstractRule copy, AbstractRule orig, Map<RuleWithParameterValues, AbstractRule> origToCopy) {
|
||||
var parameterValues = new RuleWithParameterValues(orig)
|
||||
parameterValues.attachToEmfObject(copy)
|
||||
origToCopy.put(parameterValues, copy)
|
||||
}
|
||||
|
||||
def private boolean allAreTerminalRules(Collection<AbstractRule> callers) {
|
||||
return callers.forall[it instanceof TerminalRule]
|
||||
}
|
||||
|
||||
def private <T extends EObject> T copy(T t) {
|
||||
var T result = EcoreUtil.create(t.eClass()) as T
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.preferences;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.xtext.preferences.IPreferenceValues;
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
|
||||
@EmfAdaptable
|
||||
@SuppressWarnings("all")
|
||||
public class PreferenceValuesByLanguage {
|
||||
public static class PreferenceValuesByLanguageAdapter extends AdapterImpl {
|
||||
private PreferenceValuesByLanguage element;
|
||||
|
||||
public PreferenceValuesByLanguageAdapter(final PreferenceValuesByLanguage element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public PreferenceValuesByLanguage get() {
|
||||
return this.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(final Object object) {
|
||||
return object == PreferenceValuesByLanguage.class;
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<String, IPreferenceValues> preferencesByLanguage = CollectionLiterals.<String, IPreferenceValues>newHashMap();
|
||||
|
||||
public IPreferenceValues get(final String languageId) {
|
||||
return this.preferencesByLanguage.get(languageId);
|
||||
}
|
||||
|
||||
public IPreferenceValues put(final String languageId, final IPreferenceValues values) {
|
||||
return this.preferencesByLanguage.put(languageId, values);
|
||||
}
|
||||
|
||||
public static PreferenceValuesByLanguage findInEmfObject(final Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters()) {
|
||||
if (adapter instanceof PreferenceValuesByLanguage.PreferenceValuesByLanguageAdapter) {
|
||||
return ((PreferenceValuesByLanguage.PreferenceValuesByLanguageAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PreferenceValuesByLanguage removeFromEmfObject(final Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for(int i = 0, max = adapters.size(); i < max; i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof PreferenceValuesByLanguage.PreferenceValuesByLanguageAdapter) {
|
||||
emfObject.eAdapters().remove(i);
|
||||
return ((PreferenceValuesByLanguage.PreferenceValuesByLanguageAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(final Notifier emfObject) {
|
||||
PreferenceValuesByLanguage result = findInEmfObject(emfObject);
|
||||
if (result != null)
|
||||
throw new IllegalStateException("The given EMF object already contains an adapter for PreferenceValuesByLanguage");
|
||||
PreferenceValuesByLanguage.PreferenceValuesByLanguageAdapter adapter = new PreferenceValuesByLanguage.PreferenceValuesByLanguageAdapter(this);
|
||||
emfObject.eAdapters().add(adapter);
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2014 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtext.resource.XtextResourceSet;
|
||||
import org.eclipse.xtext.service.OperationCanceledError;
|
||||
import org.eclipse.xtext.service.OperationCanceledManager;
|
||||
import org.eclipse.xtext.util.CancelIndicator;
|
||||
import org.eclipse.xtext.util.concurrent.CancelableUnitOfWork;
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class OutdatedStateManager {
|
||||
@Inject
|
||||
private OperationCanceledManager canceledManager;
|
||||
|
||||
private final ThreadLocal<Boolean> cancelationAllowed = new ThreadLocal<Boolean>() {
|
||||
@Override
|
||||
public Boolean initialValue() {
|
||||
return Boolean.valueOf(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Created a fresh CancelIndicator
|
||||
*/
|
||||
public CancelIndicator newCancelIndicator(final ResourceSet rs) {
|
||||
CancelIndicator _xifexpression = null;
|
||||
if ((rs instanceof XtextResourceSet)) {
|
||||
final boolean cancelationAllowed = (this.cancelationAllowed.get()).booleanValue();
|
||||
final int current = ((XtextResourceSet)rs).getModificationStamp();
|
||||
final CancelIndicator _function = () -> {
|
||||
return (cancelationAllowed && (((XtextResourceSet)rs).isOutdated() || (current != ((XtextResourceSet)rs).getModificationStamp())));
|
||||
};
|
||||
return _function;
|
||||
} else {
|
||||
_xifexpression = CancelIndicator.NullImpl;
|
||||
}
|
||||
return _xifexpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given ResourceSet is in an outdated state and
|
||||
* throws an {@link OperationCanceledError} if so.
|
||||
*/
|
||||
public void checkCanceled(final ResourceSet rs) {
|
||||
if ((rs instanceof XtextResourceSet)) {
|
||||
if ((((XtextResourceSet)rs).isOutdated() && (this.cancelationAllowed.get()).booleanValue())) {
|
||||
this.canceledManager.throwOperationCanceledException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <R extends Object, P extends Resource> R exec(final IUnitOfWork<R, P> work, final P param) {
|
||||
try {
|
||||
R _xblockexpression = null;
|
||||
{
|
||||
final Boolean wasCancelationAllowed = this.cancelationAllowed.get();
|
||||
R _xtrycatchfinallyexpression = null;
|
||||
try {
|
||||
R _xblockexpression_1 = null;
|
||||
{
|
||||
if ((work instanceof CancelableUnitOfWork<?, ?>)) {
|
||||
CancelIndicator _xifexpression = null;
|
||||
if ((param == null)) {
|
||||
final CancelIndicator _function = () -> {
|
||||
return true;
|
||||
};
|
||||
_xifexpression = _function;
|
||||
} else {
|
||||
_xifexpression = this.newCancelIndicator(param.getResourceSet());
|
||||
}
|
||||
((CancelableUnitOfWork<?, ?>)work).setCancelIndicator(_xifexpression);
|
||||
} else {
|
||||
this.cancelationAllowed.set(Boolean.valueOf(false));
|
||||
}
|
||||
_xblockexpression_1 = work.exec(param);
|
||||
}
|
||||
_xtrycatchfinallyexpression = _xblockexpression_1;
|
||||
} finally {
|
||||
this.cancelationAllowed.set(wasCancelationAllowed);
|
||||
}
|
||||
_xblockexpression = _xtrycatchfinallyexpression;
|
||||
}
|
||||
return _xblockexpression;
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2016 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import org.eclipse.xtext.ISetup;
|
||||
import org.eclipse.xtext.resource.FileExtensionProvider;
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider;
|
||||
import org.eclipse.xtext.resource.impl.ResourceServiceProviderRegistryImpl;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
* @since 2.11
|
||||
*/
|
||||
@Singleton
|
||||
@SuppressWarnings("all")
|
||||
public class ResourceServiceProviderServiceLoader implements Provider<IResourceServiceProvider.Registry> {
|
||||
private ServiceLoader<ISetup> setupLoader = ServiceLoader.<ISetup>load(ISetup.class);
|
||||
|
||||
private IResourceServiceProvider.Registry registry = this.loadRegistry();
|
||||
|
||||
private IResourceServiceProvider.Registry loadRegistry() {
|
||||
final ResourceServiceProviderRegistryImpl registry = new ResourceServiceProviderRegistryImpl();
|
||||
for (final ISetup cp : this.setupLoader) {
|
||||
{
|
||||
final Injector injector = cp.createInjectorAndDoEMFRegistration();
|
||||
final IResourceServiceProvider resourceServiceProvider = injector.<IResourceServiceProvider>getInstance(IResourceServiceProvider.class);
|
||||
final FileExtensionProvider extensionProvider = injector.<FileExtensionProvider>getInstance(FileExtensionProvider.class);
|
||||
Set<String> _fileExtensions = extensionProvider.getFileExtensions();
|
||||
for (final String ext : _fileExtensions) {
|
||||
boolean _containsKey = registry.getExtensionToFactoryMap().containsKey(ext);
|
||||
if (_containsKey) {
|
||||
String _primaryFileExtension = extensionProvider.getPrimaryFileExtension();
|
||||
boolean _equals = Objects.equal(_primaryFileExtension, ext);
|
||||
if (_equals) {
|
||||
registry.getExtensionToFactoryMap().put(ext, resourceServiceProvider);
|
||||
}
|
||||
} else {
|
||||
registry.getExtensionToFactoryMap().put(ext, resourceServiceProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceServiceProvider.Registry get() {
|
||||
return this.registry;
|
||||
}
|
||||
}
|
|
@ -1,220 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2017 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.containers;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.Iterables;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
|
||||
import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor;
|
||||
import org.eclipse.xtext.naming.QualifiedName;
|
||||
import org.eclipse.xtext.resource.IContainer;
|
||||
import org.eclipse.xtext.resource.IEObjectDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.LiveShadowedChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData;
|
||||
import org.eclipse.xtext.workspace.IProjectConfig;
|
||||
import org.eclipse.xtext.workspace.ISourceFolder;
|
||||
import org.eclipse.xtext.workspace.IWorkspaceConfig;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.14
|
||||
*/
|
||||
@Beta
|
||||
@FinalFieldsConstructor
|
||||
@SuppressWarnings("all")
|
||||
public class LiveShadowedChunkedContainer implements IContainer {
|
||||
private final LiveShadowedChunkedResourceDescriptions descriptions;
|
||||
|
||||
private final String containerName;
|
||||
|
||||
private IProjectConfig projectConfig;
|
||||
|
||||
private boolean isProjectConfigSet = false;
|
||||
|
||||
protected ChunkedResourceDescriptions getChunkedResourceDescriptions() {
|
||||
IResourceDescriptions _globalDescriptions = this.descriptions.getGlobalDescriptions();
|
||||
return ((ChunkedResourceDescriptions) _globalDescriptions);
|
||||
}
|
||||
|
||||
protected IProjectConfig getProjectConfig() {
|
||||
if ((!this.isProjectConfigSet)) {
|
||||
IWorkspaceConfig _workspaceConfig = this.descriptions.getWorkspaceConfig();
|
||||
IProjectConfig _findProjectByName = null;
|
||||
if (_workspaceConfig!=null) {
|
||||
_findProjectByName=_workspaceConfig.findProjectByName(this.containerName);
|
||||
}
|
||||
this.projectConfig = _findProjectByName;
|
||||
this.isProjectConfigSet = true;
|
||||
}
|
||||
return this.projectConfig;
|
||||
}
|
||||
|
||||
protected ResourceDescriptionsData getChunk() {
|
||||
ResourceDescriptionsData _elvis = null;
|
||||
ResourceDescriptionsData _container = this.getChunkedResourceDescriptions().getContainer(this.containerName);
|
||||
if (_container != null) {
|
||||
_elvis = _container;
|
||||
} else {
|
||||
ResourceDescriptionsData _resourceDescriptionsData = new ResourceDescriptionsData(Collections.<IResourceDescription>unmodifiableList(CollectionLiterals.<IResourceDescription>newArrayList()));
|
||||
_elvis = _resourceDescriptionsData;
|
||||
}
|
||||
return _elvis;
|
||||
}
|
||||
|
||||
protected Iterable<IResourceDescription> getContainedLocalDescriptions() {
|
||||
final Function1<IResourceDescription, Boolean> _function = (IResourceDescription it) -> {
|
||||
return Boolean.valueOf(this.isContained(it.getURI()));
|
||||
};
|
||||
return IterableExtensions.<IResourceDescription>filter(this.descriptions.getLocalDescriptions().getAllResourceDescriptions(), _function);
|
||||
}
|
||||
|
||||
protected boolean isContained(final URI uri) {
|
||||
boolean _or = false;
|
||||
IResourceDescription _resourceDescription = this.getChunk().getResourceDescription(uri);
|
||||
boolean _tripleNotEquals = (_resourceDescription != null);
|
||||
if (_tripleNotEquals) {
|
||||
_or = true;
|
||||
} else {
|
||||
IProjectConfig _projectConfig = this.getProjectConfig();
|
||||
ISourceFolder _findSourceFolderContaining = null;
|
||||
if (_projectConfig!=null) {
|
||||
_findSourceFolderContaining=_projectConfig.findSourceFolderContaining(uri);
|
||||
}
|
||||
boolean _tripleNotEquals_1 = (_findSourceFolderContaining != null);
|
||||
_or = _tripleNotEquals_1;
|
||||
}
|
||||
return _or;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceDescription getResourceDescription(final URI uri) {
|
||||
IResourceDescription _xifexpression = null;
|
||||
boolean _isContained = this.isContained(uri);
|
||||
if (_isContained) {
|
||||
_xifexpression = this.descriptions.getResourceDescription(uri);
|
||||
} else {
|
||||
_xifexpression = null;
|
||||
}
|
||||
return _xifexpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResourceDescriptionCount() {
|
||||
return IterableExtensions.size(this.getResourceDescriptions());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IResourceDescription> getResourceDescriptions() {
|
||||
final Set<URI> localURIs = this.getExistingOrRenamedResourceURIs();
|
||||
Iterable<IResourceDescription> _containedLocalDescriptions = this.getContainedLocalDescriptions();
|
||||
final Function1<IResourceDescription, Boolean> _function = (IResourceDescription it) -> {
|
||||
boolean _contains = localURIs.contains(it.getURI());
|
||||
return Boolean.valueOf((!_contains));
|
||||
};
|
||||
Iterable<IResourceDescription> _filter = IterableExtensions.<IResourceDescription>filter(this.getChunk().getAllResourceDescriptions(), _function);
|
||||
return Iterables.<IResourceDescription>concat(_containedLocalDescriptions, _filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResourceDescription(final URI uri) {
|
||||
IResourceDescription _resourceDescription = this.getChunk().getResourceDescription(uri);
|
||||
return (_resourceDescription != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjects() {
|
||||
final Set<URI> localURIs = this.getExistingOrRenamedResourceURIs();
|
||||
final Function1<IResourceDescription, Iterable<IEObjectDescription>> _function = (IResourceDescription it) -> {
|
||||
return it.getExportedObjects();
|
||||
};
|
||||
final Iterable<IEObjectDescription> flatten = Iterables.<IEObjectDescription>concat(IterableExtensions.<IResourceDescription, Iterable<IEObjectDescription>>map(this.getContainedLocalDescriptions(), _function));
|
||||
final Function1<IEObjectDescription, Boolean> _function_1 = (IEObjectDescription it) -> {
|
||||
boolean _contains = localURIs.contains(it.getEObjectURI().trimFragment());
|
||||
return Boolean.valueOf((!_contains));
|
||||
};
|
||||
Iterable<IEObjectDescription> _filter = IterableExtensions.<IEObjectDescription>filter(this.getChunk().getExportedObjects(), _function_1);
|
||||
return Iterables.<IEObjectDescription>concat(flatten, _filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjects(final EClass type, final QualifiedName name, final boolean ignoreCase) {
|
||||
final Set<URI> localURIs = this.getExistingOrRenamedResourceURIs();
|
||||
final Function1<IResourceDescription, Iterable<IEObjectDescription>> _function = (IResourceDescription it) -> {
|
||||
return it.getExportedObjects(type, name, ignoreCase);
|
||||
};
|
||||
Iterable<IEObjectDescription> _flatten = Iterables.<IEObjectDescription>concat(IterableExtensions.<IResourceDescription, Iterable<IEObjectDescription>>map(this.getContainedLocalDescriptions(), _function));
|
||||
final Function1<IEObjectDescription, Boolean> _function_1 = (IEObjectDescription it) -> {
|
||||
boolean _contains = localURIs.contains(it.getEObjectURI().trimFragment());
|
||||
return Boolean.valueOf((!_contains));
|
||||
};
|
||||
Iterable<IEObjectDescription> _filter = IterableExtensions.<IEObjectDescription>filter(this.getChunk().getExportedObjects(type, name, ignoreCase), _function_1);
|
||||
return Iterables.<IEObjectDescription>concat(_flatten, _filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjectsByObject(final EObject object) {
|
||||
final Set<URI> localURIs = this.getExistingOrRenamedResourceURIs();
|
||||
final Function1<IResourceDescription, Iterable<IEObjectDescription>> _function = (IResourceDescription it) -> {
|
||||
return it.getExportedObjectsByObject(object);
|
||||
};
|
||||
Iterable<IEObjectDescription> _flatten = Iterables.<IEObjectDescription>concat(IterableExtensions.<IResourceDescription, Iterable<IEObjectDescription>>map(this.getContainedLocalDescriptions(), _function));
|
||||
final Function1<IEObjectDescription, Boolean> _function_1 = (IEObjectDescription it) -> {
|
||||
boolean _contains = localURIs.contains(it.getEObjectURI().trimFragment());
|
||||
return Boolean.valueOf((!_contains));
|
||||
};
|
||||
Iterable<IEObjectDescription> _filter = IterableExtensions.<IEObjectDescription>filter(this.getChunk().getExportedObjectsByObject(object), _function_1);
|
||||
return Iterables.<IEObjectDescription>concat(_flatten, _filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IEObjectDescription> getExportedObjectsByType(final EClass type) {
|
||||
final Set<URI> localURIs = this.getExistingOrRenamedResourceURIs();
|
||||
final Function1<IResourceDescription, Iterable<IEObjectDescription>> _function = (IResourceDescription it) -> {
|
||||
return it.getExportedObjectsByType(type);
|
||||
};
|
||||
Iterable<IEObjectDescription> _flatten = Iterables.<IEObjectDescription>concat(IterableExtensions.<IResourceDescription, Iterable<IEObjectDescription>>map(this.getContainedLocalDescriptions(), _function));
|
||||
final Function1<IEObjectDescription, Boolean> _function_1 = (IEObjectDescription it) -> {
|
||||
boolean _contains = localURIs.contains(it.getEObjectURI().trimFragment());
|
||||
return Boolean.valueOf((!_contains));
|
||||
};
|
||||
Iterable<IEObjectDescription> _filter = IterableExtensions.<IEObjectDescription>filter(this.getChunk().getExportedObjectsByType(type), _function_1);
|
||||
return Iterables.<IEObjectDescription>concat(_flatten, _filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return (IterableExtensions.isEmpty(this.getContainedLocalDescriptions()) && this.getChunk().isEmpty());
|
||||
}
|
||||
|
||||
protected Set<URI> getExistingOrRenamedResourceURIs() {
|
||||
final ResourceSet resourceSet = this.descriptions.getResourceSet();
|
||||
if ((resourceSet instanceof ResourceSetImpl)) {
|
||||
return ((ResourceSetImpl)resourceSet).getURIResourceMap().keySet();
|
||||
}
|
||||
throw new IllegalStateException("ResourceSet is not a ResourceSetImpl");
|
||||
}
|
||||
|
||||
public LiveShadowedChunkedContainer(final LiveShadowedChunkedResourceDescriptions descriptions, final String containerName) {
|
||||
super();
|
||||
this.descriptions = descriptions;
|
||||
this.containerName = containerName;
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2017 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.containers;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtext.resource.IContainer;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.containers.LiveShadowedChunkedContainer;
|
||||
import org.eclipse.xtext.resource.impl.ChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.LiveShadowedChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ProjectDescription;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsBasedContainer;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
@SuppressWarnings("all")
|
||||
public class ProjectDescriptionBasedContainerManager implements IContainer.Manager {
|
||||
public boolean shouldUseProjectDescriptionBasedContainers(final IResourceDescriptions resourceDescriptions) {
|
||||
final ChunkedResourceDescriptions chunkedResourceDescriptions = this.getChunkedResourceDescriptions(resourceDescriptions);
|
||||
return (((chunkedResourceDescriptions != null) && (chunkedResourceDescriptions.getResourceSet() != null)) && (ProjectDescription.findInEmfObject(chunkedResourceDescriptions.getResourceSet()) != null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IContainer getContainer(final IResourceDescription desc, final IResourceDescriptions resourceDescriptions) {
|
||||
final ChunkedResourceDescriptions chunkedResourceDescriptions = this.getChunkedResourceDescriptions(resourceDescriptions);
|
||||
if ((chunkedResourceDescriptions == null)) {
|
||||
String _name = ChunkedResourceDescriptions.class.getName();
|
||||
String _plus = ("expected " + _name);
|
||||
throw new IllegalArgumentException(_plus);
|
||||
}
|
||||
final ResourceSet resourceSet = chunkedResourceDescriptions.getResourceSet();
|
||||
final ProjectDescription projectDescription = ProjectDescription.findInEmfObject(resourceSet);
|
||||
final IContainer container = this.createContainer(resourceDescriptions, chunkedResourceDescriptions, projectDescription.getName());
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IContainer> getVisibleContainers(final IResourceDescription desc, final IResourceDescriptions resourceDescriptions) {
|
||||
final ChunkedResourceDescriptions chunkedResourceDescriptions = this.getChunkedResourceDescriptions(resourceDescriptions);
|
||||
if ((chunkedResourceDescriptions == null)) {
|
||||
String _name = ChunkedResourceDescriptions.class.getName();
|
||||
String _plus = ("expected " + _name);
|
||||
throw new IllegalArgumentException(_plus);
|
||||
}
|
||||
final ResourceSet resourceSet = chunkedResourceDescriptions.getResourceSet();
|
||||
final ProjectDescription projectDescription = ProjectDescription.findInEmfObject(resourceSet);
|
||||
final ArrayList<IContainer> allContainers = CollectionLiterals.<IContainer>newArrayList();
|
||||
allContainers.add(this.createContainer(resourceDescriptions, chunkedResourceDescriptions, projectDescription.getName()));
|
||||
List<String> _dependencies = projectDescription.getDependencies();
|
||||
for (final String name : _dependencies) {
|
||||
allContainers.add(this.createContainer(resourceDescriptions, chunkedResourceDescriptions, name));
|
||||
}
|
||||
return allContainers;
|
||||
}
|
||||
|
||||
protected ChunkedResourceDescriptions getChunkedResourceDescriptions(final IResourceDescriptions resourceDescriptions) {
|
||||
ChunkedResourceDescriptions _switchResult = null;
|
||||
boolean _matched = false;
|
||||
if (resourceDescriptions instanceof ChunkedResourceDescriptions) {
|
||||
_matched=true;
|
||||
_switchResult = ((ChunkedResourceDescriptions)resourceDescriptions);
|
||||
}
|
||||
if (!_matched) {
|
||||
if (resourceDescriptions instanceof LiveShadowedChunkedResourceDescriptions) {
|
||||
_matched=true;
|
||||
_switchResult = this.getChunkedResourceDescriptions(((LiveShadowedChunkedResourceDescriptions)resourceDescriptions).getGlobalDescriptions());
|
||||
}
|
||||
}
|
||||
if (!_matched) {
|
||||
_switchResult = null;
|
||||
}
|
||||
return _switchResult;
|
||||
}
|
||||
|
||||
protected IContainer createContainer(final IResourceDescriptions resourceDescriptions, final ChunkedResourceDescriptions chunkedResourceDescriptions, final String projectName) {
|
||||
IContainer _xifexpression = null;
|
||||
if ((resourceDescriptions instanceof LiveShadowedChunkedResourceDescriptions)) {
|
||||
_xifexpression = new LiveShadowedChunkedContainer(((LiveShadowedChunkedResourceDescriptions)resourceDescriptions), projectName);
|
||||
} else {
|
||||
ResourceDescriptionsData _elvis = null;
|
||||
ResourceDescriptionsData _container = chunkedResourceDescriptions.getContainer(projectName);
|
||||
if (_container != null) {
|
||||
_elvis = _container;
|
||||
} else {
|
||||
Set<IResourceDescription> _emptySet = CollectionLiterals.<IResourceDescription>emptySet();
|
||||
ResourceDescriptionsData _resourceDescriptionsData = new ResourceDescriptionsData(_emptySet);
|
||||
_elvis = _resourceDescriptionsData;
|
||||
}
|
||||
_xifexpression = new ResourceDescriptionsBasedContainer(_elvis);
|
||||
}
|
||||
return _xifexpression;
|
||||
}
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2016 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.impl;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.Iterables;
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.ISelectable;
|
||||
import org.eclipse.xtext.resource.containers.ProjectDescriptionBasedContainerManager;
|
||||
import org.eclipse.xtext.resource.impl.AbstractCompoundSelectable;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsData;
|
||||
import org.eclipse.xtext.resource.persistence.SerializableResourceDescription;
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.ExclusiveRange;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
|
||||
/**
|
||||
* A IResourceDescriptions implementation that holds its resource description in chunks, each identified by a string.
|
||||
* The strings represent units such as projects, source sets, and libraries.
|
||||
*
|
||||
* @see ProjectDescription
|
||||
* @see ProjectDescriptionBasedContainerManager
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
@EmfAdaptable
|
||||
@SuppressWarnings("all")
|
||||
public class ChunkedResourceDescriptions extends AbstractCompoundSelectable implements IResourceDescriptions, Externalizable {
|
||||
public static class ChunkedResourceDescriptionsAdapter extends AdapterImpl {
|
||||
private ChunkedResourceDescriptions element;
|
||||
|
||||
public ChunkedResourceDescriptionsAdapter(final ChunkedResourceDescriptions element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public ChunkedResourceDescriptions get() {
|
||||
return this.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(final Object object) {
|
||||
return object == ChunkedResourceDescriptions.class;
|
||||
}
|
||||
}
|
||||
|
||||
protected ConcurrentHashMap<String, ResourceDescriptionsData> chunk2resourceDescriptions = new ConcurrentHashMap<String, ResourceDescriptionsData>();
|
||||
|
||||
protected ResourceSet resourceSet;
|
||||
|
||||
public ChunkedResourceDescriptions() {
|
||||
}
|
||||
|
||||
public ChunkedResourceDescriptions(final Map<String, ResourceDescriptionsData> initialData) {
|
||||
ConcurrentHashMap<String, ResourceDescriptionsData> _concurrentHashMap = new ConcurrentHashMap<String, ResourceDescriptionsData>(initialData);
|
||||
this.chunk2resourceDescriptions = _concurrentHashMap;
|
||||
}
|
||||
|
||||
public ChunkedResourceDescriptions(final Map<String, ResourceDescriptionsData> initialData, final ResourceSet resourceSet) {
|
||||
this(initialData);
|
||||
this.setResourceSet(resourceSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of the resource descriptions map and installs it with the given ResourceSet.
|
||||
*/
|
||||
public ChunkedResourceDescriptions createShallowCopyWith(final ResourceSet resourceSet) {
|
||||
return new ChunkedResourceDescriptions(this.chunk2resourceDescriptions, resourceSet);
|
||||
}
|
||||
|
||||
public ResourceSet getResourceSet() {
|
||||
return this.resourceSet;
|
||||
}
|
||||
|
||||
protected void setResourceSet(final ResourceSet resourceSet) {
|
||||
if ((this.resourceSet != null)) {
|
||||
String _name = this.getClass().getName();
|
||||
String _plus = ("This " + _name);
|
||||
String _plus_1 = (_plus + " is already associated with a different resource set.");
|
||||
throw new IllegalStateException(_plus_1);
|
||||
}
|
||||
final ChunkedResourceDescriptions index = ChunkedResourceDescriptions.findInEmfObject(resourceSet);
|
||||
if ((index != null)) {
|
||||
String _name_1 = this.getClass().getName();
|
||||
String _plus_2 = ("There is already a different " + _name_1);
|
||||
String _plus_3 = (_plus_2 + " installed in the given resource set.");
|
||||
throw new IllegalStateException(_plus_3);
|
||||
}
|
||||
this.resourceSet = resourceSet;
|
||||
this.attachToEmfObject(resourceSet);
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData setContainer(final String name, final ResourceDescriptionsData descriptions) {
|
||||
return this.chunk2resourceDescriptions.put(name, descriptions);
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData removeContainer(final String name) {
|
||||
return this.chunk2resourceDescriptions.remove(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<? extends ISelectable> getSelectables() {
|
||||
return this.chunk2resourceDescriptions.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IResourceDescription> getAllResourceDescriptions() {
|
||||
final Function1<ResourceDescriptionsData, Iterable<IResourceDescription>> _function = (ResourceDescriptionsData it) -> {
|
||||
return it.getAllResourceDescriptions();
|
||||
};
|
||||
return Iterables.<IResourceDescription>concat(IterableExtensions.<ResourceDescriptionsData, Iterable<IResourceDescription>>map(this.chunk2resourceDescriptions.values(), _function));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceDescription getResourceDescription(final URI uri) {
|
||||
Collection<ResourceDescriptionsData> _values = this.chunk2resourceDescriptions.values();
|
||||
for (final ResourceDescriptionsData selectable : _values) {
|
||||
{
|
||||
final IResourceDescription result = selectable.getResourceDescription(uri);
|
||||
if ((result != null)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData getContainer(final URI uri) {
|
||||
Collection<ResourceDescriptionsData> _values = this.chunk2resourceDescriptions.values();
|
||||
for (final ResourceDescriptionsData container : _values) {
|
||||
{
|
||||
final IResourceDescription result = container.getResourceDescription(uri);
|
||||
if ((result != null)) {
|
||||
return container;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResourceDescriptionsData getContainer(final String containerHandle) {
|
||||
return this.chunk2resourceDescriptions.get(containerHandle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
final int numChunks = in.readInt();
|
||||
ExclusiveRange _doubleDotLessThan = new ExclusiveRange(0, numChunks, true);
|
||||
for (final Integer i : _doubleDotLessThan) {
|
||||
{
|
||||
final String chunkName = in.readUTF();
|
||||
final int numDescriptions = in.readInt();
|
||||
final ArrayList<IResourceDescription> descriptions = new ArrayList<IResourceDescription>(numDescriptions);
|
||||
ExclusiveRange _doubleDotLessThan_1 = new ExclusiveRange(0, numDescriptions, true);
|
||||
for (final Integer j : _doubleDotLessThan_1) {
|
||||
Object _readObject = in.readObject();
|
||||
descriptions.add(((IResourceDescription) _readObject));
|
||||
}
|
||||
ResourceDescriptionsData _resourceDescriptionsData = new ResourceDescriptionsData(descriptions);
|
||||
this.chunk2resourceDescriptions.put(chunkName, _resourceDescriptionsData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(final ObjectOutput out) throws IOException {
|
||||
final HashMap<String, ResourceDescriptionsData> copy = new HashMap<String, ResourceDescriptionsData>(this.chunk2resourceDescriptions);
|
||||
out.writeInt(copy.entrySet().size());
|
||||
final Consumer<Map.Entry<String, ResourceDescriptionsData>> _function = (Map.Entry<String, ResourceDescriptionsData> it) -> {
|
||||
try {
|
||||
out.writeUTF(it.getKey());
|
||||
final Function1<IResourceDescription, Object> _function_1 = (IResourceDescription it_1) -> {
|
||||
Object _xifexpression = null;
|
||||
if ((it_1 instanceof Serializable)) {
|
||||
_xifexpression = ((Object)it_1);
|
||||
} else {
|
||||
_xifexpression = SerializableResourceDescription.createCopy(it_1);
|
||||
}
|
||||
return ((Object)_xifexpression);
|
||||
};
|
||||
final Iterable<Object> descriptions = IterableExtensions.<IResourceDescription, Object>map(it.getValue().getAllResourceDescriptions(), _function_1);
|
||||
out.writeInt(IterableExtensions.size(descriptions));
|
||||
final Consumer<Object> _function_2 = (Object it_1) -> {
|
||||
try {
|
||||
out.writeObject(it_1);
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
};
|
||||
descriptions.forEach(_function_2);
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
};
|
||||
copy.entrySet().forEach(_function);
|
||||
}
|
||||
|
||||
public static ChunkedResourceDescriptions findInEmfObject(final Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters()) {
|
||||
if (adapter instanceof ChunkedResourceDescriptions.ChunkedResourceDescriptionsAdapter) {
|
||||
return ((ChunkedResourceDescriptions.ChunkedResourceDescriptionsAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ChunkedResourceDescriptions removeFromEmfObject(final Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for(int i = 0, max = adapters.size(); i < max; i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof ChunkedResourceDescriptions.ChunkedResourceDescriptionsAdapter) {
|
||||
emfObject.eAdapters().remove(i);
|
||||
return ((ChunkedResourceDescriptions.ChunkedResourceDescriptionsAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(final Notifier emfObject) {
|
||||
ChunkedResourceDescriptions result = findInEmfObject(emfObject);
|
||||
if (result != null)
|
||||
throw new IllegalStateException("The given EMF object already contains an adapter for ChunkedResourceDescriptions");
|
||||
ChunkedResourceDescriptions.ChunkedResourceDescriptionsAdapter adapter = new ChunkedResourceDescriptions.ChunkedResourceDescriptionsAdapter(this);
|
||||
emfObject.eAdapters().add(adapter);
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2011, 2017 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.impl;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtend.lib.annotations.AccessorType;
|
||||
import org.eclipse.xtend.lib.annotations.Accessors;
|
||||
import org.eclipse.xtext.EcoreUtil2;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ChunkedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.LiveShadowedResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ResourceSetBasedResourceDescriptions;
|
||||
import org.eclipse.xtext.workspace.IProjectConfig;
|
||||
import org.eclipse.xtext.workspace.IProjectConfigProvider;
|
||||
import org.eclipse.xtext.workspace.IWorkspaceConfig;
|
||||
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
|
||||
/**
|
||||
* @author Jan Koehnlein - Initial contribution and API
|
||||
* @since 2.14
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class LiveShadowedChunkedResourceDescriptions extends LiveShadowedResourceDescriptions {
|
||||
@Inject(optional = true)
|
||||
private IProjectConfigProvider projectConfigProvider;
|
||||
|
||||
@Accessors(AccessorType.PUBLIC_GETTER)
|
||||
private IWorkspaceConfig workspaceConfig;
|
||||
|
||||
@Override
|
||||
public void setContext(final Notifier ctx) {
|
||||
IResourceDescriptions _localDescriptions = this.getLocalDescriptions();
|
||||
final Procedure1<ResourceSetBasedResourceDescriptions> _function = (ResourceSetBasedResourceDescriptions it) -> {
|
||||
it.setContext(ctx);
|
||||
it.setData(null);
|
||||
};
|
||||
ObjectExtensions.<ResourceSetBasedResourceDescriptions>operator_doubleArrow(((ResourceSetBasedResourceDescriptions) _localDescriptions), _function);
|
||||
final ResourceSet resourceSet = EcoreUtil2.getResourceSet(ctx);
|
||||
this.setGlobalDescriptions(ChunkedResourceDescriptions.findInEmfObject(resourceSet));
|
||||
IProjectConfig _projectConfig = null;
|
||||
if (this.projectConfigProvider!=null) {
|
||||
_projectConfig=this.projectConfigProvider.getProjectConfig(resourceSet);
|
||||
}
|
||||
IWorkspaceConfig _workspaceConfig = null;
|
||||
if (_projectConfig!=null) {
|
||||
_workspaceConfig=_projectConfig.getWorkspaceConfig();
|
||||
}
|
||||
this.workspaceConfig = _workspaceConfig;
|
||||
}
|
||||
|
||||
@Pure
|
||||
public IWorkspaceConfig getWorkspaceConfig() {
|
||||
return this.workspaceConfig;
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015, 2017 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.resource.impl;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import java.util.List;
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.xtend.lib.annotations.Accessors;
|
||||
import org.eclipse.xtend.lib.annotations.ToString;
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
@Beta
|
||||
@ToString
|
||||
@EmfAdaptable
|
||||
@SuppressWarnings("all")
|
||||
public class ProjectDescription {
|
||||
public static class ProjectDescriptionAdapter extends AdapterImpl {
|
||||
private ProjectDescription element;
|
||||
|
||||
public ProjectDescriptionAdapter(final ProjectDescription element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public ProjectDescription get() {
|
||||
return this.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(final Object object) {
|
||||
return object == ProjectDescription.class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A unique name for this project
|
||||
*/
|
||||
@Accessors
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* list of logical names of upstream dependencies
|
||||
*/
|
||||
@Accessors
|
||||
private List<String> dependencies = CollectionLiterals.<String>newArrayList();
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this);
|
||||
b.add("name", this.name);
|
||||
b.add("dependencies", this.dependencies);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static ProjectDescription findInEmfObject(final Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters()) {
|
||||
if (adapter instanceof ProjectDescription.ProjectDescriptionAdapter) {
|
||||
return ((ProjectDescription.ProjectDescriptionAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ProjectDescription removeFromEmfObject(final Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for(int i = 0, max = adapters.size(); i < max; i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof ProjectDescription.ProjectDescriptionAdapter) {
|
||||
emfObject.eAdapters().remove(i);
|
||||
return ((ProjectDescription.ProjectDescriptionAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(final Notifier emfObject) {
|
||||
ProjectDescription result = findInEmfObject(emfObject);
|
||||
if (result != null)
|
||||
throw new IllegalStateException("The given EMF object already contains an adapter for ProjectDescription");
|
||||
ProjectDescription.ProjectDescriptionAdapter adapter = new ProjectDescription.ProjectDescriptionAdapter(this);
|
||||
emfObject.eAdapters().add(adapter);
|
||||
}
|
||||
|
||||
@Pure
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Pure
|
||||
public List<String> getDependencies() {
|
||||
return this.dependencies;
|
||||
}
|
||||
|
||||
public void setDependencies(final List<String> dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
}
|
|
@ -1,482 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.xtext;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.Notifier;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.EReference;
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil;
|
||||
import org.eclipse.xtend.lib.annotations.Accessors;
|
||||
import org.eclipse.xtext.AbstractElement;
|
||||
import org.eclipse.xtext.AbstractRule;
|
||||
import org.eclipse.xtext.CompoundElement;
|
||||
import org.eclipse.xtext.Condition;
|
||||
import org.eclipse.xtext.EnumRule;
|
||||
import org.eclipse.xtext.Grammar;
|
||||
import org.eclipse.xtext.GrammarUtil;
|
||||
import org.eclipse.xtext.Group;
|
||||
import org.eclipse.xtext.NamedArgument;
|
||||
import org.eclipse.xtext.Parameter;
|
||||
import org.eclipse.xtext.ParserRule;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
import org.eclipse.xtext.TerminalRule;
|
||||
import org.eclipse.xtext.TypeRef;
|
||||
import org.eclipse.xtext.XtextPackage;
|
||||
import org.eclipse.xtext.util.internal.EmfAdaptable;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.ListExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure2;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xtext.ConditionEvaluator;
|
||||
import org.eclipse.xtext.xtext.OriginalElement;
|
||||
import org.eclipse.xtext.xtext.OriginalGrammar;
|
||||
import org.eclipse.xtext.xtext.RuleFilter;
|
||||
import org.eclipse.xtext.xtext.RuleNames;
|
||||
import org.eclipse.xtext.xtext.RuleWithParameterValues;
|
||||
import org.eclipse.xtext.xtext.UsedRulesFinder;
|
||||
|
||||
/**
|
||||
* @author Sebastian Zarnekow - Initial contribution and API
|
||||
*/
|
||||
@EmfAdaptable
|
||||
@SuppressWarnings("all")
|
||||
public class FlattenedGrammarAccess {
|
||||
public static class FlattenedGrammarAccessAdapter extends AdapterImpl {
|
||||
private FlattenedGrammarAccess element;
|
||||
|
||||
public FlattenedGrammarAccessAdapter(final FlattenedGrammarAccess element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public FlattenedGrammarAccess get() {
|
||||
return this.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(final Object object) {
|
||||
return object == FlattenedGrammarAccess.class;
|
||||
}
|
||||
}
|
||||
|
||||
@Accessors
|
||||
private final Grammar flattenedGrammar;
|
||||
|
||||
public FlattenedGrammarAccess(final RuleNames names, final RuleFilter filter) {
|
||||
final Grammar grammar = names.getContextGrammar();
|
||||
Grammar flattenedGrammar = this.<Grammar>copy(grammar);
|
||||
flattenedGrammar.setName(grammar.getName());
|
||||
LinkedHashMap<RuleWithParameterValues, AbstractRule> origToCopy = Maps.<RuleWithParameterValues, AbstractRule>newLinkedHashMap();
|
||||
final ArrayList<AbstractRule> copies = this.copyRuleStubs(names, origToCopy, filter.getRules(grammar), filter.isDiscardRuleTypeRef());
|
||||
EList<AbstractRule> _rules = flattenedGrammar.getRules();
|
||||
Iterables.<AbstractRule>addAll(_rules, copies);
|
||||
Multimap<TerminalRule, AbstractRule> calledFrom = this.copyRuleBodies(copies, origToCopy);
|
||||
this.setHiddenTokens(flattenedGrammar, grammar, origToCopy);
|
||||
this.markAsFragment(calledFrom);
|
||||
boolean _isDiscardUnreachableRules = filter.isDiscardUnreachableRules();
|
||||
if (_isDiscardUnreachableRules) {
|
||||
Set<AbstractRule> usedRules = CollectionLiterals.<AbstractRule>newHashSet();
|
||||
boolean _isDiscardTerminalRules = filter.isDiscardTerminalRules();
|
||||
boolean _not = (!_isDiscardTerminalRules);
|
||||
if (_not) {
|
||||
usedRules.addAll(GrammarUtil.allTerminalRules(flattenedGrammar));
|
||||
}
|
||||
UsedRulesFinder finder = new UsedRulesFinder(usedRules);
|
||||
finder.compute(flattenedGrammar);
|
||||
flattenedGrammar.getRules().retainAll(usedRules);
|
||||
}
|
||||
this.flattenedGrammar = flattenedGrammar;
|
||||
new OriginalGrammar(grammar).attachToEmfObject(flattenedGrammar);
|
||||
}
|
||||
|
||||
private void setHiddenTokens(final Grammar copy, final Grammar orig, final Map<RuleWithParameterValues, AbstractRule> origToCopy) {
|
||||
if ((orig == null)) {
|
||||
copy.setDefinesHiddenTokens(true);
|
||||
} else {
|
||||
boolean _isDefinesHiddenTokens = orig.isDefinesHiddenTokens();
|
||||
boolean _not = (!_isDefinesHiddenTokens);
|
||||
if (_not) {
|
||||
this.setHiddenTokens(copy, IterableExtensions.<Grammar>head(orig.getUsedGrammars()), origToCopy);
|
||||
} else {
|
||||
copy.setDefinesHiddenTokens(true);
|
||||
EList<AbstractRule> _hiddenTokens = copy.getHiddenTokens();
|
||||
final Function1<AbstractRule, AbstractRule> _function = (AbstractRule hidden) -> {
|
||||
RuleWithParameterValues _ruleWithParameterValues = new RuleWithParameterValues(hidden);
|
||||
return origToCopy.get(_ruleWithParameterValues);
|
||||
};
|
||||
List<AbstractRule> _map = ListExtensions.<AbstractRule, AbstractRule>map(orig.getHiddenTokens(), _function);
|
||||
Iterables.<AbstractRule>addAll(_hiddenTokens, _map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void markAsFragment(final Multimap<TerminalRule, AbstractRule> calledFrom) {
|
||||
final Function1<TerminalRule, Boolean> _function = (TerminalRule it) -> {
|
||||
boolean _isFragment = it.isFragment();
|
||||
return Boolean.valueOf((!_isFragment));
|
||||
};
|
||||
final Function1<TerminalRule, Boolean> _function_1 = (TerminalRule it) -> {
|
||||
return Boolean.valueOf(this.allAreTerminalRules(calledFrom.get(it)));
|
||||
};
|
||||
final Function1<TerminalRule, Boolean> _function_2 = (TerminalRule it) -> {
|
||||
EObject _eContainer = it.eContainer();
|
||||
boolean _contains = ((Grammar) _eContainer).getHiddenTokens().contains(it);
|
||||
return Boolean.valueOf((!_contains));
|
||||
};
|
||||
final Consumer<TerminalRule> _function_3 = (TerminalRule it) -> {
|
||||
it.setFragment(true);
|
||||
};
|
||||
IterableExtensions.<TerminalRule>filter(IterableExtensions.<TerminalRule>filter(IterableExtensions.<TerminalRule>filter(calledFrom.keySet(), _function), _function_1), _function_2).forEach(_function_3);
|
||||
}
|
||||
|
||||
private Multimap<TerminalRule, AbstractRule> copyRuleBodies(final List<AbstractRule> copies, final Map<RuleWithParameterValues, AbstractRule> origToCopy) {
|
||||
abstract class __FlattenedGrammarAccess_1 extends EcoreUtil.Copier {
|
||||
final __FlattenedGrammarAccess_1 _this__FlattenedGrammarAccess_1 = this;
|
||||
|
||||
abstract Set<Parameter> getParameterConfig(final RuleCall origRuleCall, final RuleCall copyRuleCall);
|
||||
|
||||
abstract void mergePredicates(final AbstractElement into, final AbstractElement from);
|
||||
|
||||
abstract void mergeCardinalities(final AbstractElement into, final AbstractElement from);
|
||||
|
||||
abstract boolean evaluate(final Condition condition);
|
||||
}
|
||||
|
||||
final HashMultimap<TerminalRule, AbstractRule> calledFrom = HashMultimap.<TerminalRule, AbstractRule>create();
|
||||
for (final AbstractRule copy : copies) {
|
||||
{
|
||||
AbstractRule orig = RuleWithParameterValues.getOriginalRule(copy);
|
||||
final Set<Parameter> paramValues = RuleWithParameterValues.getParamValues(copy);
|
||||
EcoreUtil.Copier copier = new __FlattenedGrammarAccess_1() {
|
||||
@Override
|
||||
protected void copyReference(final EReference eReference, final EObject eObject, final EObject copyEObject) {
|
||||
if ((eReference == XtextPackage.Literals.RULE_CALL__RULE)) {
|
||||
RuleCall origRuleCall = ((RuleCall) eObject);
|
||||
RuleCall copyRuleCall = ((RuleCall) copyEObject);
|
||||
AbstractRule _rule = origRuleCall.getRule();
|
||||
Set<Parameter> _parameterConfig = this.getParameterConfig(origRuleCall, copyRuleCall);
|
||||
RuleWithParameterValues _ruleWithParameterValues = new RuleWithParameterValues(_rule, _parameterConfig);
|
||||
AbstractRule calledCopy = origToCopy.get(_ruleWithParameterValues);
|
||||
copyRuleCall.setRule(calledCopy);
|
||||
if ((calledCopy instanceof TerminalRule)) {
|
||||
calledFrom.put(((TerminalRule)calledCopy), copy);
|
||||
}
|
||||
} else {
|
||||
super.copyReference(eReference, eObject, copyEObject);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Parameter> getParameterConfig(final RuleCall origRuleCall, final RuleCall copyRuleCall) {
|
||||
boolean _isEmpty = origRuleCall.getArguments().isEmpty();
|
||||
if (_isEmpty) {
|
||||
return Collections.<Parameter>emptySet();
|
||||
}
|
||||
final Function1<NamedArgument, Boolean> _function = (NamedArgument it) -> {
|
||||
return Boolean.valueOf(this.evaluate(it.getValue()));
|
||||
};
|
||||
final Function1<NamedArgument, Parameter> _function_1 = (NamedArgument it) -> {
|
||||
return it.getParameter();
|
||||
};
|
||||
Set<Parameter> result = IterableExtensions.<Parameter>toSet(IterableExtensions.<NamedArgument, Parameter>map(IterableExtensions.<NamedArgument>filter(origRuleCall.getArguments(), _function), _function_1));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void copyContainment(final EReference eReference, final EObject eObject, final EObject copyEObject) {
|
||||
boolean _matched = false;
|
||||
if (Objects.equal(eReference, XtextPackage.Literals.RULE_CALL__ARGUMENTS)) {
|
||||
_matched=true;
|
||||
}
|
||||
if (!_matched) {
|
||||
if (Objects.equal(eReference, XtextPackage.Literals.GROUP__GUARD_CONDITION)) {
|
||||
_matched=true;
|
||||
}
|
||||
}
|
||||
if (_matched) {
|
||||
return;
|
||||
}
|
||||
super.copyContainment(eReference, eObject, copyEObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EObject copy(final EObject eObject) {
|
||||
if ((eObject instanceof Group)) {
|
||||
Group group = ((Group)eObject);
|
||||
Condition _guardCondition = group.getGuardCondition();
|
||||
boolean _tripleNotEquals = (_guardCondition != null);
|
||||
if (_tripleNotEquals) {
|
||||
boolean _evaluate = this.evaluate(group.getGuardCondition());
|
||||
boolean _not = (!_evaluate);
|
||||
if (_not) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
EObject result = super.copy(eObject);
|
||||
if ((result instanceof CompoundElement)) {
|
||||
List<AbstractElement> elements = ((CompoundElement)result).getElements();
|
||||
int _size = elements.size();
|
||||
boolean _tripleEquals = (_size == 1);
|
||||
if (_tripleEquals) {
|
||||
if (((!((CompoundElement)result).isFirstSetPredicated()) && (!((CompoundElement)result).isPredicated()))) {
|
||||
AbstractElement element = elements.get(0);
|
||||
this.mergeCardinalities(element, ((AbstractElement)result));
|
||||
this.mergePredicates(element, ((AbstractElement)result));
|
||||
return element;
|
||||
} else {
|
||||
AbstractElement element_1 = elements.get(0);
|
||||
this.mergePredicates(((AbstractElement)result), element_1);
|
||||
element_1.setFirstSetPredicated(false);
|
||||
element_1.setPredicated(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((eObject instanceof AbstractElement)) {
|
||||
OriginalElement original = new OriginalElement(((AbstractElement)eObject));
|
||||
EClass _eClass = ((AbstractElement)eObject).eClass();
|
||||
EClass _eClass_1 = result.eClass();
|
||||
boolean _notEquals = (!Objects.equal(_eClass, _eClass_1));
|
||||
if (_notEquals) {
|
||||
String _name = result.eClass().getName();
|
||||
String _plus = ("copy is: \'" + _name);
|
||||
String _plus_1 = (_plus + "\' but original was: \'");
|
||||
String _name_1 = ((AbstractElement)eObject).eClass().getName();
|
||||
String _plus_2 = (_plus_1 + _name_1);
|
||||
String _plus_3 = (_plus_2 + "\'");
|
||||
throw new IllegalStateException(_plus_3);
|
||||
}
|
||||
original.attachToEmfObject(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void mergePredicates(final AbstractElement into, final AbstractElement from) {
|
||||
boolean _isPredicated = from.isPredicated();
|
||||
if (_isPredicated) {
|
||||
into.setPredicated(true);
|
||||
into.setFirstSetPredicated(false);
|
||||
} else {
|
||||
if (((!into.isPredicated()) && from.isFirstSetPredicated())) {
|
||||
into.setFirstSetPredicated(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mergeCardinalities(final AbstractElement into, final AbstractElement from) {
|
||||
String c1 = into.getCardinality();
|
||||
String c2 = from.getCardinality();
|
||||
String _switchResult = null;
|
||||
boolean _matched = false;
|
||||
if ((Objects.equal(c1, "*") || Objects.equal(c2, "*"))) {
|
||||
_matched=true;
|
||||
}
|
||||
if (!_matched) {
|
||||
if ((Objects.equal(c1, "+") && Objects.equal(c2, "?"))) {
|
||||
_matched=true;
|
||||
}
|
||||
}
|
||||
if (!_matched) {
|
||||
if ((Objects.equal(c1, "?") && Objects.equal(c2, "+"))) {
|
||||
_matched=true;
|
||||
}
|
||||
}
|
||||
if (_matched) {
|
||||
_switchResult = "*";
|
||||
}
|
||||
if (!_matched) {
|
||||
if (Objects.equal(c1, null)) {
|
||||
_matched=true;
|
||||
_switchResult = c2;
|
||||
}
|
||||
}
|
||||
if (!_matched) {
|
||||
_switchResult = c1;
|
||||
}
|
||||
into.setCardinality(_switchResult);
|
||||
}
|
||||
|
||||
boolean evaluate(final Condition condition) {
|
||||
boolean result = new ConditionEvaluator(paramValues).evaluate(condition);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
EObject _copy = copier.copy(orig.getAlternatives());
|
||||
AbstractElement copiedBody = ((AbstractElement) _copy);
|
||||
copier.copyReferences();
|
||||
copy.setAlternatives(copiedBody);
|
||||
if ((orig instanceof ParserRule)) {
|
||||
ParserRule castedCopy = ((ParserRule) copy);
|
||||
boolean _isDefinesHiddenTokens = ((ParserRule)orig).isDefinesHiddenTokens();
|
||||
if (_isDefinesHiddenTokens) {
|
||||
castedCopy.setDefinesHiddenTokens(true);
|
||||
EList<AbstractRule> _hiddenTokens = ((ParserRule)orig).getHiddenTokens();
|
||||
for (final AbstractRule rule : _hiddenTokens) {
|
||||
{
|
||||
RuleWithParameterValues _ruleWithParameterValues = new RuleWithParameterValues(rule);
|
||||
final AbstractRule copiedTerminalRule = origToCopy.get(_ruleWithParameterValues);
|
||||
EList<AbstractRule> _hiddenTokens_1 = castedCopy.getHiddenTokens();
|
||||
_hiddenTokens_1.add(copiedTerminalRule);
|
||||
calledFrom.put(((TerminalRule) copiedTerminalRule), castedCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return calledFrom;
|
||||
}
|
||||
|
||||
private TypeRef copyTypeRef(final TypeRef ref) {
|
||||
if ((ref == null)) {
|
||||
return null;
|
||||
}
|
||||
final TypeRef copy = this.<TypeRef>copy(ref);
|
||||
copy.setClassifier(ref.getClassifier());
|
||||
return copy;
|
||||
}
|
||||
|
||||
private ArrayList<AbstractRule> copyRuleStubs(final RuleNames names, final Map<RuleWithParameterValues, AbstractRule> origToCopy, final List<AbstractRule> rulesToCopy, final boolean discardTypeRef) {
|
||||
final ArrayList<AbstractRule> result = CollectionLiterals.<AbstractRule>newArrayList();
|
||||
for (final AbstractRule rule : rulesToCopy) {
|
||||
{
|
||||
String ruleName = names.getAntlrRuleName(rule);
|
||||
boolean _matched = false;
|
||||
if (rule instanceof ParserRule) {
|
||||
_matched=true;
|
||||
List<Parameter> params = ((ParserRule)rule).getParameters();
|
||||
boolean _isEmpty = params.isEmpty();
|
||||
if (_isEmpty) {
|
||||
ParserRule copy = this.<ParserRule>copy(((ParserRule)rule));
|
||||
copy.setName(ruleName);
|
||||
copy.setFragment(((ParserRule)rule).isFragment());
|
||||
copy.setWildcard(((ParserRule)rule).isWildcard());
|
||||
if ((!discardTypeRef)) {
|
||||
copy.setType(this.copyTypeRef(((ParserRule)rule).getType()));
|
||||
}
|
||||
this.attachTo(copy, rule, origToCopy);
|
||||
result.add(copy);
|
||||
} else {
|
||||
final Procedure2<Set<Parameter>, Integer> _function = (Set<Parameter> parameterConfig, Integer i) -> {
|
||||
RuleWithParameterValues parameterValues = new RuleWithParameterValues(rule, parameterConfig);
|
||||
ParserRule copy_1 = this.<ParserRule>copy(((ParserRule)rule));
|
||||
copy_1.setName(names.getAntlrRuleName(rule, (i).intValue()));
|
||||
copy_1.setFragment(((ParserRule)rule).isFragment());
|
||||
copy_1.setWildcard(((ParserRule)rule).isWildcard());
|
||||
if ((!discardTypeRef)) {
|
||||
copy_1.setType(this.copyTypeRef(((ParserRule)rule).getType()));
|
||||
}
|
||||
origToCopy.put(parameterValues, copy_1);
|
||||
parameterValues.attachToEmfObject(copy_1);
|
||||
result.add(copy_1);
|
||||
};
|
||||
IterableExtensions.<Set<Parameter>>forEach(Sets.<Parameter>powerSet(ImmutableSet.<Parameter>copyOf(params)), _function);
|
||||
}
|
||||
}
|
||||
if (!_matched) {
|
||||
if (rule instanceof TerminalRule) {
|
||||
_matched=true;
|
||||
TerminalRule orig = ((TerminalRule)rule);
|
||||
TerminalRule copy = this.<TerminalRule>copy(orig);
|
||||
copy.setName(ruleName);
|
||||
copy.setFragment(orig.isFragment());
|
||||
this.attachTo(copy, orig, origToCopy);
|
||||
result.add(copy);
|
||||
}
|
||||
}
|
||||
if (!_matched) {
|
||||
if (rule instanceof EnumRule) {
|
||||
_matched=true;
|
||||
EnumRule copy = this.<EnumRule>copy(((EnumRule)rule));
|
||||
copy.setName(ruleName);
|
||||
this.attachTo(copy, rule, origToCopy);
|
||||
result.add(copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private AbstractRule attachTo(final AbstractRule copy, final AbstractRule orig, final Map<RuleWithParameterValues, AbstractRule> origToCopy) {
|
||||
AbstractRule _xblockexpression = null;
|
||||
{
|
||||
RuleWithParameterValues parameterValues = new RuleWithParameterValues(orig);
|
||||
parameterValues.attachToEmfObject(copy);
|
||||
_xblockexpression = origToCopy.put(parameterValues, copy);
|
||||
}
|
||||
return _xblockexpression;
|
||||
}
|
||||
|
||||
private boolean allAreTerminalRules(final Collection<AbstractRule> callers) {
|
||||
final Function1<AbstractRule, Boolean> _function = (AbstractRule it) -> {
|
||||
return Boolean.valueOf((it instanceof TerminalRule));
|
||||
};
|
||||
return IterableExtensions.<AbstractRule>forall(callers, _function);
|
||||
}
|
||||
|
||||
private <T extends EObject> T copy(final T t) {
|
||||
EObject _create = EcoreUtil.create(t.eClass());
|
||||
T result = ((T) _create);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static FlattenedGrammarAccess findInEmfObject(final Notifier emfObject) {
|
||||
for (Adapter adapter : emfObject.eAdapters()) {
|
||||
if (adapter instanceof FlattenedGrammarAccess.FlattenedGrammarAccessAdapter) {
|
||||
return ((FlattenedGrammarAccess.FlattenedGrammarAccessAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FlattenedGrammarAccess removeFromEmfObject(final Notifier emfObject) {
|
||||
List<Adapter> adapters = emfObject.eAdapters();
|
||||
for(int i = 0, max = adapters.size(); i < max; i++) {
|
||||
Adapter adapter = adapters.get(i);
|
||||
if (adapter instanceof FlattenedGrammarAccess.FlattenedGrammarAccessAdapter) {
|
||||
emfObject.eAdapters().remove(i);
|
||||
return ((FlattenedGrammarAccess.FlattenedGrammarAccessAdapter) adapter).get();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attachToEmfObject(final Notifier emfObject) {
|
||||
FlattenedGrammarAccess result = findInEmfObject(emfObject);
|
||||
if (result != null)
|
||||
throw new IllegalStateException("The given EMF object already contains an adapter for FlattenedGrammarAccess");
|
||||
FlattenedGrammarAccess.FlattenedGrammarAccessAdapter adapter = new FlattenedGrammarAccess.FlattenedGrammarAccessAdapter(this);
|
||||
emfObject.eAdapters().add(adapter);
|
||||
}
|
||||
|
||||
@Pure
|
||||
public Grammar getFlattenedGrammar() {
|
||||
return this.flattenedGrammar;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue