blob: 702d0a697d9c5ea7328666edf9be03f1a37d3a23 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.dsl.xtext.lazyresolver;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.Constants;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.resource.DerivedStateAwareResource;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.internal.Stopwatches;
import org.eclipse.xtext.util.internal.Stopwatches.StoppedTask;
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelInferrer;
import org.eclipse.xtext.xbase.jvmmodel.JvmModelAssociator;
import org.eclipse.xtext.xbase.jvmmodel.JvmModelCompleter;
import org.eclipse.xtext.xbase.lib.Pair;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.typesystem.util.Maps2;
import org.eclipse.osbp.dsl.xtext.lazyresolver.api.DerivedRootAdapter;
import org.eclipse.osbp.dsl.xtext.lazyresolver.api.IIndexDerivedStateComputer;
import org.eclipse.osbp.dsl.xtext.lazyresolver.api.IIndexModelAssociator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
@SuppressWarnings("restriction")
public class IndexDerivedStateComputer extends JvmModelAssociator implements
IIndexDerivedStateComputer, IIndexModelAssociator {
private final static Logger LOGGER = LoggerFactory
.getLogger(IndexDerivedStateComputer.class);
@Inject
@Named(Constants.LANGUAGE_NAME)
private String languageName;
@Inject
private Provider<IJvmModelInferrer> inferrerProvider;
@Inject
private JvmModelCompleter completer;
public void setCompleter(JvmModelCompleter completer) {
this.completer = completer;
}
/**
* @since 2.8
* @noreference This method is not intended to be referenced by clients
*/
public void setInferrerProvider(Provider<IJvmModelInferrer> inferrerProvider) {
this.inferrerProvider = inferrerProvider;
}
/**
* Never installs the fully derived state by invoking doLater.
*/
public void installDerivedState(final DerivedStateAwareResource resource,
boolean preIndexingPhase) {
if (resource.getContents().isEmpty())
return;
EObject eObject = resource.getContents().get(0);
StoppedTask task = Stopwatches
.forTask("JVM Model inference (JvmModelAssociator.installDerivedState)");
task.start();
JvmDeclaredTypeAcceptor acceptor = new JvmDeclaredTypeAcceptor(resource);
try {
IndexModelInferrer inferrer = (IndexModelInferrer) inferrerProvider
.get();
inferrer.setContext(resource);
inferrer.inferTypesOnly(eObject, acceptor, preIndexingPhase);
} catch (RuntimeException e) {
// LOG.error("Error calling inferrer", e);
}
task.stop();
}
/**
* Installs the complete derived state for the {@link EObject} at the given
* index in the resource.
*/
@Override
public void installDerivedState(DerivedStateAwareResource resource,
JvmDeclaredType derivedOne, boolean preIndexingPhase) {
DerivedRootAdapter derivedRootAdapter = (DerivedRootAdapter) EcoreUtil
.getAdapter(derivedOne.eAdapters(), DerivedRootAdapter.class);
EObject derivedSemantic = derivedRootAdapter.getSemantic();
StoppedTask task = Stopwatches
.forTask("JVM Model inference (JvmModelAssociator.installDerivedState)");
task.start();
JvmDeclaredTypeAcceptor acceptor = new JvmDeclaredTypeAcceptor(resource);
try {
IndexModelInferrer inferrer = (IndexModelInferrer) inferrerProvider
.get();
inferrer.setContext(resource);
// infer the full state by the inferrer
inferrer.inferFullState(derivedOne, derivedSemantic, acceptor,
preIndexingPhase, derivedRootAdapter.getSelector());
// then delegate the inferring to all extension delegates
inferrer.inferFullStateByDelegates(derivedOne, derivedSemantic,
acceptor, preIndexingPhase,
derivedRootAdapter.getSelector());
} catch (RuntimeException e) {
// LOG.error("Error calling inferrer", e);
System.out.println(e);
}
if (!preIndexingPhase) {
for (Pair<JvmDeclaredType, Procedure1<? super JvmDeclaredType>> initializer : acceptor.later) {
try {
initializer.getValue().apply(initializer.getKey());
} catch (RuntimeException e) {
// LOG.error("Error calling inferrer", e);
LOGGER.error("{}", e);
}
}
}
task.stop();
if (!preIndexingPhase) {
completer.complete(derivedOne);
}
}
protected ExtendedAdapter getOrInstall(Resource resource) {
if (!(resource instanceof XtextResource)) {
return new ExtendedAdapter();
}
String resourceLanguageName = ((XtextResource) resource)
.getLanguageName();
if (!languageName.equals(resourceLanguageName)) {
return new ExtendedAdapter();
}
Adapter adapter = (Adapter) EcoreUtil.getAdapter(resource.eAdapters(),
Adapter.class);
if (adapter == null) {
adapter = new ExtendedAdapter();
resource.eAdapters().add(adapter);
}
return (ExtendedAdapter) adapter;
}
protected Map<EObject, Set<Pair<String, JvmGenericType>>> selectorTypeMap(
Resource res) {
return getOrInstall(res).selectorTypeMap;
}
@Override
public void associateBySelector(EObject sourceElement,
JvmGenericType jvmElement, String selector) {
Resource resource = sourceElement.eResource();
Map<EObject, Set<Pair<String, JvmGenericType>>> selectorTypeMap = selectorTypeMap(resource);
Set<Pair<String, JvmGenericType>> pairs = selectorTypeMap
.get(sourceElement);
if (pairs == null) {
pairs = new HashSet<Pair<String, JvmGenericType>>(2);
selectorTypeMap.put(sourceElement, pairs);
}
pairs.add(Pair.of(selector, jvmElement));
}
@Override
public JvmGenericType getBySelector(EObject sourceElement, String selector) {
Resource resource = sourceElement.eResource();
Set<Pair<String, JvmGenericType>> pairs = selectorTypeMap(resource)
.get(sourceElement);
if (pairs != null) {
for (Pair<String, JvmGenericType> pair : pairs) {
if (pair.getKey().equals(selector)) {
return pair.getValue();
}
}
}
LOGGER.error("No registration found for " + selector + " : "
+ sourceElement);
return null;
}
protected static class ExtendedAdapter extends JvmModelAssociator.Adapter {
public Map<EObject, Set<Pair<String, JvmGenericType>>> selectorTypeMap = Maps2
.newLinkedHashMapWithExpectedSize(40);
}
}