package org.eclipse.xtend.backend.compiler;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.xtend.backend.common.BackendTypesystem;
import org.eclipse.xtend.backend.compiler.model.NamedParsedResource;
import org.eclipse.xtend.middleend.MiddleEnd;
import org.eclipse.xtend.middleend.MiddleEndFactory;
import org.eclipse.xtend.middleend.NoMiddleEndForResourceException;
import org.eclipse.xtend.middleend.plugins.ImportedResource;
import org.eclipse.xtend.middleend.plugins.LanguageSpecificMiddleEnd;
import org.eclipse.xtend.middleend.plugins.ParsedResource;
public abstract class AbstractBackendResourceCompilerFacade implements BackendCompilerFacade {
private static final Log _log = LogFactory.getLog (AbstractBackendResourceCompilerFacade.class);
protected BackendTypesystem _typeSystem;
protected List<LanguageSpecificMiddleEnd> _languageHandlers;
private MiddleEnd _middleEnd;
private boolean _initialized;
/**
* @return the initialized
*/
public boolean isInitialized() {
return _initialized;
}
/**
* @param initialized the initialized to set
*/
public void setInitialized(boolean initialized) {
_initialized = initialized;
}
public AbstractBackendResourceCompilerFacade (BackendTypesystem ts) {
_typeSystem = ts;
}
public void compile(Collection<String> resources, String contributorNamespace,
String contributorName, String outputDir,
Map<Class<?>, Object> specificParams, String fileEncoding) {
Map<String, Set<NamedParsedResource>> imports = new HashMap<String, Set<NamedParsedResource>> ();
_middleEnd = createMiddleEnd (specificParams);
Map<String, ParsedResource> parsedResources = null;
for (String res : resources) {
try {
_middleEnd.getFunctions (res);
parsedResources = _middleEnd.getParsedResources();
Set<NamedParsedResource> resImports = new HashSet<NamedParsedResource> ();
for (ImportedResource impRes : parsedResources.get(res).getImports()) {
ParsedResource curImport = parsedResources.get (impRes.getResourceName());
if (curImport != null)
resImports.add(new NamedParsedResource (impRes.getResourceName(), curImport));
}
collectReexportedResources (resImports, new HashSet<String> (), res);
imports.put (res, resImports);
compileInternal (res, parsedResources.get(res), imports, _middleEnd, _typeSystem, outputDir, fileEncoding);
} catch (NoMiddleEndForResourceException e) {
}
}
}
abstract protected void compileInternal (String resourceName, ParsedResource parsedRes, Map<String, Set<NamedParsedResource>> imports, MiddleEnd middleend, BackendTypesystem typeSystem, String outputDir, String fileEncoding);
protected MiddleEnd createMiddleEnd (Map<Class<?>, Object> specificParams) {
if (MiddleEndFactory.canCreateFromExtentions()) {
_middleEnd = MiddleEndFactory.createFromExtensions(_typeSystem, specificParams);
} else {
_middleEnd = MiddleEndFactory.create(_typeSystem, _languageHandlers);
}
if (_middleEnd != null)
_initialized = true;
return _middleEnd;
}
public void collectReexportedResources (Set<NamedParsedResource> result, Set<String> visited, String curResource) {
if (_initialized) {
ParsedResource parsedRes = _middleEnd.getParsedResources().get(curResource);
if (visited.contains (curResource))
return;
visited.add (curResource);
for (ImportedResource candidate: parsedRes.getImports()) {
final String candidateName = candidate.getResourceName();
if (visited.contains (candidateName))
continue;
if (candidate.isReexported() && parsedRes != null)
result.add (new NamedParsedResource(candidateName, _middleEnd.getParsedResources().get(candidateName)));
collectReexportedResources (result, visited, candidateName);
}
}
}
/**
* @return the typeSystem
*/
public BackendTypesystem getTypeSystem() {
return _typeSystem;
}
/**
* @param typeSystem the typeSystem to set
*/
public void setTypeSystem(BackendTypesystem typeSystem) {
_typeSystem = typeSystem;
}
/**
* @return the languageHandlers
*/
public List<LanguageSpecificMiddleEnd> getLanguageHandlers() {
return _languageHandlers;
}
/**
* @param languageHandlers the languageHandlers to set
*/
public void setLanguageHandlers(List<LanguageSpecificMiddleEnd> languageHandlers) {
_languageHandlers = languageHandlers;
}
/**
* @return the middleEnd
*/
public MiddleEnd getMiddleEnd() {
return _middleEnd;
}
/**
* @param middleEnd the middleEnd to set
*/
public void setMiddleEnd(MiddleEnd middleEnd) {
_middleEnd = middleEnd;
}
}