package org.erlide.cover.core; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import org.eclipse.core.runtime.IPath; import org.erlide.cover.api.CoverException; import org.erlide.cover.api.IConfiguration; import org.erlide.cover.api.ICoveragePerformer; import org.erlide.cover.constants.CoverConstants; import org.erlide.cover.views.model.StatsTreeModel; import org.erlide.engine.model.root.IErlModule; import org.erlide.runtime.rpc.RpcException; import org.erlide.util.ErlLogger; import com.ericsson.otp.erlang.OtpErlangAtom; import com.ericsson.otp.erlang.OtpErlangList; import com.ericsson.otp.erlang.OtpErlangObject; /** * Implementation of coverage analysis operations * * @author Aleksandra Lipiec <aleksandra.lipiec@erlang-solutions.com> * */ public class CoveragePerformer implements ICoveragePerformer { private static CoveragePerformer performer; private Collection<String> coverNodes; private IConfiguration config; private final Logger log; // logger private CoveragePerformer() { log = Activator.getDefault(); coverNodes = new LinkedList<>(); } public static synchronized CoveragePerformer getPerformer() { if (performer == null) { performer = new CoveragePerformer(); } return performer; } /** * Start cover */ @Override public synchronized void startCover(final Collection<String> nodes) throws CoverException { final StatsTreeModel model = StatsTreeModel.getInstance(); model.clear(); if (CoverBackend.getInstance().getAnnotationMaker() != null) { CoverBackend.getInstance().getAnnotationMaker().clearAllAnnotations(); } for (final ICoverObserver obs : CoverBackend.getInstance().getListeners()) { obs.eventOccured(new CoverEvent(CoverStatus.UPDATE)); } boolean different = false; for (final String node : nodes) { if (!coverNodes.contains(node)) { different = true; break; } } if (coverNodes.isEmpty() || different) { coverNodes = nodes; log.info(CoverBackend.getInstance().getBackend().getName()); coverNodes.add(CoverBackend.getInstance().getBackend().getName()); // TODO restarting final List<OtpErlangObject> names = new ArrayList<>( coverNodes.size()); for (final String name : coverNodes) { names.add(new OtpErlangAtom(name)); } final OtpErlangList nodesList = new OtpErlangList( names.toArray(new OtpErlangObject[0])); try { CoverBackend.getInstance().getBackend().getOtpRpc().call( CoverConstants.COVER_ERL_BACKEND, CoverConstants.FUN_START, "x", nodesList); } catch (final RpcException e) { ErlLogger.error(e); throw new CoverException(e.getMessage()); } } } /** * Set coverage configuration */ @Override public synchronized void setCoverageConfiguration(final IConfiguration conf) throws CoverException { config = conf; StatsTreeModel.getInstance().setRootLabel(config.getProject().getName()); final IPath ppath = config.getProject().getWorkspaceProject().getLocation(); // set include files final List<OtpErlangObject> includes = new ArrayList<>( config.getModules().size()); for (final IPath include : config.getIncludeDirs()) { log.info(ppath.append(include)); includes.add(new OtpErlangList(ppath.append(include).toString())); } try { CoverBackend.getInstance().getBackend().getOtpRpc().call( CoverConstants.COVER_ERL_BACKEND, CoverConstants.FUN_SET_INCLUDES, "x", includes); } catch (final RpcException e1) { e1.printStackTrace(); throw new CoverException(e1); } recompileModules(); } // cover compilation of chosen modules private void recompileModules() throws CoverException { final List<OtpErlangObject> paths = new ArrayList<>( config.getModules().size()); for (final IErlModule module : config.getModules()) { if (module == null) { final String msg = "No such module at given project. Check your configuration"; CoverBackend.getInstance().handleError(msg); throw new CoverException(msg); } log.info(module.getFilePath()); paths.add(new OtpErlangList(module.getFilePath())); } try { CoverBackend.getInstance().getBackend().getOtpRpc().call( CoverConstants.COVER_ERL_BACKEND, CoverConstants.FUN_PREP, "x", paths); } catch (final RpcException e) { ErlLogger.error(e); throw new CoverException(e.getMessage()); } } /** * Perform coverage analysis */ @Override public synchronized void analyse() throws CoverException { final List<OtpErlangObject> modules = new ArrayList<>( config.getModules().size()); for (final IErlModule module : config.getModules()) { log.info(module.getModuleName()); modules.add(new OtpErlangList(module.getModuleName())); } try { CoverBackend.getInstance().getBackend().getOtpRpc().call( CoverConstants.COVER_ERL_BACKEND, CoverConstants.FUN_ANALYSE, "x", modules); } catch (final RpcException e) { ErlLogger.error(e); throw new CoverException(e.getMessage()); } } /** * Allows to check configuration */ @Override public IConfiguration getConfig() { return config; } }