Package org.erlide.dialyzer.ui.handlers

Source Code of org.erlide.dialyzer.ui.handlers.RunDialyzerHandler

package org.erlide.dialyzer.ui.handlers;

import java.lang.reflect.InvocationTargetException;
import java.util.Set;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;
import org.erlide.backend.BackendCore;
import org.erlide.backend.BackendUtils;
import org.erlide.backend.api.BackendData;
import org.erlide.backend.api.IBackend;
import org.erlide.dialyzer.builder.DialyzerUtils;
import org.erlide.dialyzer.builder.DialyzerUtils.DialyzerErrorException;
import org.erlide.dialyzer.ui.Activator;
import org.erlide.engine.ErlangEngine;
import org.erlide.engine.model.ErlModelException;
import org.erlide.engine.model.IErlModel;
import org.erlide.engine.model.erlang.IErlModule;
import org.erlide.engine.model.root.IErlProject;
import org.erlide.runtime.runtimeinfo.RuntimeInfo;
import org.erlide.util.ErlLogger;
import org.erlide.util.HostnameUtils;

import com.google.common.collect.Sets;

public class RunDialyzerHandler extends AbstractHandler {

    private final class DialyzeOperation extends Job {
        private final Set<IErlModule> modules;
        private final Set<IErlProject> projects;

        public DialyzeOperation(final String name, final Set<IErlModule> modules,
                final Set<IErlProject> projects) {
            super(name);
            this.modules = modules;
            this.projects = projects;
        }

        @Override
        protected IStatus run(final IProgressMonitor monitor) {
            if (!modules.isEmpty()) {
                IBackend backend = null;
                monitor.beginTask("Dialyzing", IProgressMonitor.UNKNOWN);

                try {
                    backend = createBackend();
                    DialyzerUtils.doDialyze(monitor, modules, projects, backend);
                } catch (final OperationCanceledException e) {
                    ErlLogger.debug("Dialyzer operation was canceled");
                    return Status.CANCEL_STATUS;
                } catch (final DialyzerErrorException e) {
                    return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage());
                } catch (final InvocationTargetException e) {
                    return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getCause()
                            .getMessage());
                } finally {
                    if (backend != null) {
                        backend.dispose();
                    }
                    monitor.done();
                }

                ErlLogger.debug("Dialyzer operation ended successfully");
            }
            return Status.OK_STATUS;
        }

        private IBackend createBackend() {
            final RuntimeInfo erlideRuntime = BackendCore.getRuntimeInfoCatalog()
                    .getErlideRuntime();
            if (erlideRuntime == null) {
                return null;
            }
            final RuntimeInfo info = new RuntimeInfo(erlideRuntime);
            final BackendData data = new BackendData(info);
            final String nodeName = BackendUtils.getErlideNodeNameTag() + "_dialyzer";
            data.setNodeName(nodeName);
            data.setDebug(false);
            data.setConsole(false);
            data.setInternal(true);
            data.setLongName(HostnameUtils.canUseLongNames());
            return BackendCore.getBackendManager().createExecutionBackend(data);
        }
    }

    private final class BuildOperation extends WorkspaceJob {
        private final Set<IErlProject> projects;

        public BuildOperation(final String name, final Set<IErlProject> projects) {
            super(name);
            this.projects = projects;
        }

        @Override
        public IStatus runInWorkspace(final IProgressMonitor monitor)
                throws CoreException {
            for (final IErlProject erlProject : projects) {
                final IProject project = erlProject.getWorkspaceProject();
                project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
            }
            return Status.OK_STATUS;
        }

        @Override
        public boolean belongsTo(final Object family) {
            return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
        }

    }

    @Override
    public Object execute(final ExecutionEvent event) throws ExecutionException {
        final ISelection selection = HandlerUtil.getCurrentSelection(event);
        final Set<IErlModule> modules = collectModulesFromSelection(selection);
        final Set<IErlProject> projects = collectProjectsFromModules(modules);

        // build
        final WorkspaceJob buildJob = new BuildOperation("Building projects", projects);
        buildJob.setUser(true);
        buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule());
        buildJob.schedule();

        // run dialyzer
        final Job job = new DialyzeOperation("Running Dialyzer", modules, projects);
        final ISchedulingRule rule = createRuleForModules(modules);
        job.setRule(rule);
        job.setUser(true);
        job.schedule();
        return null;
    }

    private ISchedulingRule createRuleForModules(final Set<IErlModule> modules) {
        ISchedulingRule combinedRule = null;
        for (final IErlModule module : modules) {
            final IResource res = module.getResource();
            if (res instanceof IFile) {
                combinedRule = MultiRule.combine(combinedRule, res);
            }
        }
        return combinedRule;
    }

    private Set<IErlModule> collectModulesFromSelection(final ISelection selection) {
        final Set<IErlModule> modules = Sets.newHashSet();
        if (selection instanceof IStructuredSelection) {
            final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
            final IErlModel model = ErlangEngine.getInstance().getModel();
            try {
                model.open(null);
                for (final Object i : structuredSelection.toList()) {
                    if (i instanceof IResource) {
                        final IResource r = (IResource) i;
                        modules.addAll(DialyzerUtils.collectModulesFromResource(model, r));
                    }
                }
            } catch (final ErlModelException e) {
                ErlLogger.debug(e);
            }
        }
        return modules;
    }

    private Set<IErlProject> collectProjectsFromModules(final Set<IErlModule> modules) {
        final Set<IErlProject> projects = Sets.newHashSet();
        for (final IErlModule module : modules) {
            final IErlProject project = ErlangEngine.getInstance().getModelUtilService()
                    .getProject(module);
            projects.add(project);
        }
        return projects;
    }

}
TOP

Related Classes of org.erlide.dialyzer.ui.handlers.RunDialyzerHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.