Package org.eclim.plugin.cdt.command.src

Source Code of org.eclim.plugin.cdt.command.src.SrcUpdateCommand

/**
* Copyright (C) 2005 - 2013  Eric Van Dewoestine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.eclim.plugin.cdt.command.src;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.eclim.annotation.Command;

import org.eclim.command.CommandLine;
import org.eclim.command.Error;
import org.eclim.command.Options;

import org.eclim.plugin.cdt.util.CUtils;

import org.eclim.plugin.core.command.AbstractCommand;

import org.eclim.plugin.core.util.ProjectUtils;

import org.eclim.util.CollectionUtils;

import org.eclim.util.file.FileOffsets;

import org.eclipse.cdt.codan.core.model.CheckerLaunchMode;
import org.eclipse.cdt.codan.internal.core.CodanRunner;

import org.eclipse.cdt.core.CCorePlugin;

import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;

import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager;

import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;

import org.eclipse.cdt.core.parser.IProblem;

import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;

import org.eclipse.core.runtime.NullProgressMonitor;

/**
* Command to update the file on the eclipse side and optionally validate it.
*
* @author Eric Van Dewoestine
*/
@Command(
  name = "c_src_update",
  options =
    "REQUIRED p project ARG," +
    "REQUIRED f file ARG," +
    "OPTIONAL v validate NOARG," +
    "OPTIONAL b build NOARG"
)
public class SrcUpdateCommand
  extends AbstractCommand
{
  // Taken from org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper
  private static final int AST_STYLE =
    ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT |
    ITranslationUnit.AST_SKIP_INDEXED_HEADERS;

  @Override
  public Object execute(CommandLine commandLine)
    throws Exception
  {
    String file = commandLine.getValue(Options.FILE_OPTION);
    String projectName = commandLine.getValue(Options.PROJECT_OPTION);

    IProject project = ProjectUtils.getProject(projectName);
    ICProject cproject = CUtils.getCProject(project);
    if(cproject.exists()){
      ITranslationUnit src = CUtils.getTranslationUnit(cproject, file);

      // refresh the index
      CCorePlugin.getIndexManager().update(
          new ICElement[]{src}, IIndexManager.UPDATE_ALL);

      if(commandLine.hasOption(Options.VALIDATE_OPTION)){
        List<IProblem> problems = getProblems(src);
        ArrayList<Error> errors = new ArrayList<Error>();
        String filename = src.getResource()
          .getLocation().toOSString().replace('\\', '/');
        FileOffsets offsets = FileOffsets.compile(filename);
        for(IProblem problem : problems){
          int[] lineColumn = offsets.offsetToLineColumn(problem.getSourceStart());
          errors.add(new Error(
              problem.getMessage(),
              filename,
              lineColumn[0],
              lineColumn[1],
              problem.isWarning()));
        }

        IMarker[] markers = getMarkers(src);
        for(IMarker marker : markers){
          // skip task markers (FIXME, etc)
          if (marker.isSubtypeOf(IMarker.TASK)){
            continue;
          }

          int[] lineColumn = null;

          Integer start = (Integer)marker.getAttribute(IMarker.CHAR_START);
          if (start != null && start.intValue() > 0){
            lineColumn = offsets.offsetToLineColumn(start.intValue());
          }else{
            Integer line = (Integer)marker.getAttribute(IMarker.LINE_NUMBER);
            if (line != null && line.intValue() > 0){
              lineColumn = new int[]{line.intValue(), 1};
            }
          }

          if (lineColumn == null){
            continue;
          }

          Integer severity = (Integer)marker.getAttribute(IMarker.SEVERITY);
          errors.add(new Error(
              (String)marker.getAttribute(IMarker.MESSAGE),
              filename,
              lineColumn[0],
              lineColumn[1],
              severity == null || severity.intValue() != IMarker.SEVERITY_ERROR));
        }

        Collections.sort(errors, new Comparator<Error>(){
          public int compare(Error e1, Error e2){
            if (e1.getLine() != e2.getLine()){
              return e1.getLine() - e2.getLine();
            }
            if (e1.getColumn() != e2.getColumn()){
              return e1.getColumn() - e2.getColumn();
            }
            return 0;
          }
          public boolean equals(Object obj){
            return false;
          }
        });

        if(commandLine.hasOption(Options.BUILD_OPTION)){
          project.build(
              IncrementalProjectBuilder.INCREMENTAL_BUILD,
              new NullProgressMonitor());
        }
        return errors;
      }
    }
    return null;
  }

  private List<IProblem> getProblems(ITranslationUnit src)
    throws Exception
  {
    IIndex index = null;
    try {
      ICProject[] projects = CoreModel.getDefault().getCModel().getCProjects();
      index = CCorePlugin.getIndexManager().getIndex(projects);
      index.acquireReadLock();

      IASTTranslationUnit ast = src.getAST(index, AST_STYLE);
      ArrayList<IProblem> problems = new ArrayList<IProblem>();
      CollectionUtils.addAll(problems, ast.getPreprocessorProblems());
      CollectionUtils.addAll(problems, CPPVisitor.getProblems(ast));

      return problems;
    } finally {
      if (index != null){
        index.releaseReadLock();
      }
    }
  }

  private IMarker[] getMarkers(ITranslationUnit src)
    throws Exception
  {
    // run cdt checkers for non syntactic problems.
    IResource resource = src.getResource();
    CodanRunner.processResource(
        resource, CheckerLaunchMode.RUN_ON_DEMAND, new NullProgressMonitor());
    return resource.findMarkers(null, true, IResource.DEPTH_ZERO);
  }
}
TOP

Related Classes of org.eclim.plugin.cdt.command.src.SrcUpdateCommand

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.