Exemple #1
0
// Returns true on error.
static bool format(std::string FileName) {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return true;
  }
  if (Code->getBufferSize() == 0)
    return true; // Empty files are formatted correctly.
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  std::vector<CharSourceRange> Ranges;
  if (fillRanges(Sources, ID, Code.get(), Ranges))
    return true;

  FormatStyle FormatStyle = getStyle(Style, FileName);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources,
            getFormattingLangOpts(FormatStyle.Standard));
  tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs()
        << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>"
                   << I->getReplacementText() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Replaces.size() == 0)
        return false; // Nothing changed, don't touch the file.

      std::string ErrorInfo;
      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                      llvm::sys::fs::F_Binary);
      if (!ErrorInfo.empty()) {
        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
        return true;
      }
      Rewrite.getEditBuffer(ID).write(FileStream);
      FileStream.flush();
    } else {
      if (Cursor.getNumOccurrences() != 0)
        outs() << "{ \"Cursor\": " << tooling::shiftedCodePosition(
                                          Replaces, Cursor) << " }\n";
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemple #2
0
// Returns true on error.
static bool format(StringRef FileName) {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  std::unique_ptr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return true;
  }
  if (Code->getBufferSize() == 0)
    return false; // Empty files are formatted correctly.
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  std::vector<CharSourceRange> Ranges;
  if (fillRanges(Sources, ID, Code.get(), Ranges))
    return true;

  FormatStyle FormatStyle = getStyle(
      Style, (FileName == "-") ? AssumeFilename : FileName, FallbackStyle);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources,
            getFormattingLangOpts(FormatStyle.Standard));
  tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs()
        << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>";
      outputReplacementXML(I->getReplacementText());
      llvm::outs() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Rewrite.overwriteChangedFiles())
        return true;
    } else {
      if (Cursor.getNumOccurrences() != 0)
        outs() << "{ \"Cursor\": "
               << tooling::shiftedCodePosition(Replaces, Cursor) << " }\n";
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemple #3
0
int RefactoringTool::runAndSave(FrontendActionFactory *ActionFactory) {
  if (int Result = run(ActionFactory)) {
    return Result;
  }

  LangOptions DefaultLangOptions;
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts);
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
      &*DiagOpts, &DiagnosticPrinter, false);
  SourceManager Sources(Diagnostics, getFiles());
  Rewriter Rewrite(Sources, DefaultLangOptions);

  if (!applyAllReplacements(Rewrite)) {
    llvm::errs() << "Skipped some replacements.\n";
  }

  return saveRewrittenFiles(Rewrite);
}
int RefactoringTool::run(FrontendActionFactory *ActionFactory) {
  int Result = Tool.run(ActionFactory);
  LangOptions DefaultLangOptions;
  DiagnosticOptions DefaultDiagnosticOptions;
  TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(),
                                          DefaultDiagnosticOptions);
  DiagnosticsEngine Diagnostics(
      llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
      &DiagnosticPrinter, false);
  SourceManager Sources(Diagnostics, Tool.getFiles());
  Rewriter Rewrite(Sources, DefaultLangOptions);
  if (!applyAllReplacements(Replace, Rewrite)) {
    llvm::errs() << "Skipped some replacements.\n";
  }
  if (!saveRewrittenFiles(Rewrite)) {
    llvm::errs() << "Could not save rewritten files.\n";
    return 1;
  }
  return Result;
}
Exemple #5
0
QString CSMesEmma::exportEMMAStatistic(const QString &filename,int coverage_level,Instrumentation::coverage_method_t method) const
{
  const ExecutionNames executions=selectedExecutions();
  int nb_executions=executions.count();
  if (nb_executions==0)
    return QObject::tr("No executions selected");

  QFile f;
  f.setFileName(filename);
  if (f.open(QFile::WriteOnly))
  {
    bool is_test_count_mode_selected=isTestCountModeSelected();

    CSMesInstrumentations _instrumentations ;
    copyInstrumentation(_instrumentations,instrumentations);
    selectExecutionsComparaison(_instrumentations,executions,ExecutionNames(),is_test_count_mode_selected,method,false);
    CSMesInstrumentations _instrumentations_block ;
    copyInstrumentation(_instrumentations_block,instrumentations);
    selectExecutionsComparaison(_instrumentations_block,executions,ExecutionNames(),is_test_count_mode_selected,Instrumentation::COVERAGE_BRANCH,false);
    ExecutionNames::const_iterator it_fct;
    const QList<CSMesFunctionInfo::functionskey_t> functions= Functions();
    int nb_functions=functions.count();
    QHash<CSMesFunctionInfo::functionskey_t,int> nb_tested_function_list;
    QHash<CSMesFunctionInfo::functionskey_t,int> nb_untested_function_list;
    QSet<QString> classes;
    if ( statisticFunctionsExecution(executions,coverage_level,method,nb_tested_function_list,nb_untested_function_list,_instrumentations) )
    {
      for ( QList<CSMesFunctionInfo::functionskey_t>::const_iterator itFunction=functions.begin();itFunction<functions.end();++itFunction++)
      {
        const CSMesFunctionInfo::functionskey_t &f=*itFunction;
        if (nb_tested_function_list.contains(f) && nb_untested_function_list.contains(f) )
        {
          const QString &func=f.method.getScopedName();
          classes+=classFromFunction(func);
        }
      }
    }
    int nb_class=classes.count();

    QHash<ExecutionName,int> nb_tested_source_list;
    QHash<ExecutionName,int> nb_untested_source_list;
    const SourceFiles sources= Sources(NON_EMPTY);
    int nb_sources=sources.count();
    statisticSourcesExecution(sources,executions,coverage_level,method,nb_tested_source_list,nb_untested_source_list,_instrumentations) ;

    int nb_tested,nb_untested;
    statistic(coverage_level,method,nb_tested,nb_untested,_instrumentations) ;

    int nb_tested_block,nb_untested_block;
    statistic(coverage_level,Instrumentation::COVERAGE_BRANCH,nb_tested_block,nb_untested_block,_instrumentations_block) ;

    QHash<ExecutionName,int> nb_tested_source_block_list;
    QHash<ExecutionName,int> nb_untested_source_block_list;
    statisticSourcesExecution(sources,executions,coverage_level,Instrumentation::COVERAGE_BRANCH,nb_tested_source_block_list,nb_untested_source_block_list,_instrumentations_block) ;

    QHash<CSMesFunctionInfo::functionskey_t,int> nb_tested_function_block_list;
    QHash<CSMesFunctionInfo::functionskey_t,int> nb_untested_function_block_list;
    statisticFunctionsExecution(executions,coverage_level,Instrumentation::COVERAGE_BRANCH,nb_tested_function_block_list,nb_untested_function_block_list,_instrumentations_block) ;

    int nb_instrumentation=0;
    for (CSMesInstrumentations::Modules::const_iterator mod_it=_instrumentations.modules.begin();mod_it!=_instrumentations.modules.end();++mod_it)
      nb_instrumentation += mod_it->nb_measurements_items;


    QXmlStreamWriter stream(&f);
    stream.setAutoFormatting(true);
    stream.writeStartDocument();
    stream.writeStartElement("report");

    stream.writeStartElement("stats");

    stream.writeEmptyElement("packages");
    stream.writeAttribute("value",QString::number(1));

    stream.writeEmptyElement("methods");
    stream.writeAttribute("value",QString::number(nb_functions));

    stream.writeEmptyElement("srcfiles");
    stream.writeAttribute("value",QString::number(nb_sources));

    stream.writeEmptyElement("srclines");
    stream.writeAttribute("value",QString::number(nb_tested+nb_untested));

    stream.writeEmptyElement("classes");
    stream.writeAttribute("value",QString::number(nb_class));
    stream.writeEndElement();

    stream.writeStartElement("data");
    stream.writeStartElement("all");
    stream.writeAttribute("name","all classes");

    {
      int nb_tested_line=nb_tested;
      int nb_untested_line=nb_untested;
      int nb_tested_method;
      int nb_untested_method;
      int nb_tested_class;
      int nb_untested_class;
      int nb_tested_blocks=nb_tested_block;
      int nb_untested_blocks=nb_untested_block;
      emmaStatisticMethods(nb_tested_function_list,nb_tested_method,nb_untested_method);
      emmaStatisticClasses(nb_tested_function_list,nb_tested_class,nb_untested_class);

      exportEmmaStatistics(stream,nb_tested_line,nb_untested_line,nb_tested_method,nb_untested_method,nb_tested_class,nb_untested_class,nb_tested_blocks,nb_untested_blocks);
    }
    stream.writeStartElement("packages");
    stream.writeAttribute("name",getFilename());

    for (SourceFiles::const_iterator itSrc=sources.begin();itSrc!=sources.end();++itSrc)
    {
      stream.writeStartElement("srcfile");
      stream.writeAttribute("name",*itSrc);
      QList<CSMesFunctionInfo::functionskey_t> functions_source;
      QSet<QString> classes_source;
      for (QList<CSMesFunctionInfo::functionskey_t>::const_iterator itMeth=functions.begin();itMeth!=functions.end();++itMeth)
      {
        if ((*itMeth).source==*itSrc)
        {
          functions_source+=*itMeth;
          const QString &func=(*itMeth).method.getScopedName();
          classes_source+=classFromFunction(func);
        }
      }
      {
        int nb_tested_line=0;
        int nb_untested_line=0;
        if (nb_tested_source_list.contains(*itSrc) && nb_untested_source_list.contains(*itSrc) )
        {
          nb_tested_line=nb_tested_source_list[*itSrc];
          nb_untested_line=nb_untested_source_list[*itSrc];
        }
        QHash<CSMesFunctionInfo::functionskey_t,int> nb_tested_functions;
        for (QHash<CSMesFunctionInfo::functionskey_t,int>::const_iterator itFunc=nb_tested_function_list.begin();itFunc!=nb_tested_function_list.end();++itFunc)
        {
          if (itFunc.key().source==*itSrc)
            nb_tested_functions[itFunc.key()]=itFunc.value();
        }
        int nb_tested_method=0;
        int nb_untested_method=0;
        int nb_tested_class=0;
        int nb_untested_class=0;
        int nb_tested_blocks=0;
        int nb_untested_blocks=0;
        if (nb_tested_source_block_list.contains(*itSrc) && nb_untested_source_block_list.contains(*itSrc) )
        {
          nb_tested_blocks=nb_tested_source_block_list[*itSrc];
          nb_untested_blocks=nb_untested_source_block_list[*itSrc];
        }
        emmaStatisticMethods(nb_tested_functions,nb_tested_method,nb_untested_method);
        emmaStatisticClasses(nb_tested_functions,nb_tested_class,nb_untested_class);

        exportEmmaStatistics(stream,nb_tested_line,nb_untested_line,nb_tested_method,nb_untested_method,nb_tested_class,nb_untested_class,nb_tested_blocks,nb_untested_blocks);
      }
      for (QSet<QString>::const_iterator itClass=classes_source.begin();itClass!=classes_source.end();++itClass)
      {
        stream.writeStartElement("class");
        stream.writeAttribute("name",*itClass);
        {
          int nb_tested_line=0;
          int nb_untested_line=0;
          int nb_tested_blocks=0;
          int nb_untested_blocks=0;
          QHash<CSMesFunctionInfo::functionskey_t,int> nb_tested_functions;
          for (QHash<CSMesFunctionInfo::functionskey_t,int>::const_iterator itFunc=nb_tested_function_list.begin();itFunc!=nb_tested_function_list.end();++itFunc)
          {
            if ( (itFunc.key().source==*itSrc) && (classFromFunction(itFunc.key().method.getScopedName())==*itClass))
            {
              nb_tested_functions[itFunc.key()]=itFunc.value();
              nb_tested_line+=itFunc.value();
              nb_untested_line+=nb_untested_function_list[itFunc.key()];
              nb_tested_blocks+=nb_tested_function_block_list[itFunc.key()];
              nb_untested_blocks+=nb_untested_function_block_list[itFunc.key()];
            }
          }
          int nb_tested_method=0;
          int nb_untested_method=0;
          int nb_tested_class=0;
          int nb_untested_class=0;
          emmaStatisticMethods(nb_tested_functions,nb_tested_method,nb_untested_method);
          emmaStatisticClasses(nb_tested_functions,nb_tested_class,nb_untested_class);

          exportEmmaStatistics(stream,nb_tested_line,nb_untested_line,nb_tested_method,nb_untested_method,nb_tested_class,nb_untested_class,nb_tested_blocks,nb_untested_blocks);
        }
        for (QList<CSMesFunctionInfo::functionskey_t>::const_iterator itMeth=functions_source.begin();itMeth!=functions_source.end();++itMeth)
        {
          if ( classFromFunction(itMeth->method.getScopedName())==*itClass)
          {
            stream.writeStartElement("method");
            stream.writeAttribute("name",(*itMeth).method.getScopedName());
            {
              int nb_tested_line=0;
              int nb_untested_line=0;
              int nb_tested_blocks=0;
              int nb_untested_blocks=0;
              QHash<CSMesFunctionInfo::functionskey_t,int> nb_tested_functions;
              for (QHash<CSMesFunctionInfo::functionskey_t,int>::const_iterator itFunc=nb_tested_function_list.begin();itFunc!=nb_tested_function_list.end();++itFunc)
              {
                if ( itFunc.key()==*itMeth )
                {
                  nb_tested_functions[itFunc.key()]=itFunc.value();
                  nb_tested_line+=itFunc.value();
                  nb_untested_line+=nb_untested_function_list[itFunc.key()];
                  nb_tested_blocks+=nb_tested_function_block_list[itFunc.key()];
                  nb_untested_blocks+=nb_untested_function_block_list[itFunc.key()];
                }
              }
              int nb_tested_method=0;
              int nb_untested_method=0;
              emmaStatisticMethods(nb_tested_functions,nb_tested_method,nb_untested_method);

              exportEmmaStatistics(stream,nb_tested_line,nb_untested_line,nb_tested_method,nb_untested_method,-1,-1,nb_tested_blocks,nb_untested_blocks);
            }
            stream.writeEndElement();
          }
        }
        stream.writeEndElement();
      }
      stream.writeEndElement();
    }

    stream.writeEndElement();
    stream.writeEndElement();
    stream.writeEndElement();
    stream.writeEndDocument();
    f.close();
    return QString();
  }
  else
    return QObject::tr("Error opening file '%1':%2").arg(filename).arg(f.errorString());
}
Exemple #6
0
// Returns true on error.
static bool format(std::string FileName) {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return true;
  }
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
  if (Offsets.empty())
    Offsets.push_back(0);
  if (Offsets.size() != Lengths.size() &&
      !(Offsets.size() == 1 && Lengths.empty())) {
    llvm::errs()
        << "error: number of -offset and -length arguments must match.\n";
    return true;
  }
  std::vector<CharSourceRange> Ranges;
  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
    if (Offsets[i] >= Code->getBufferSize()) {
      llvm::errs() << "error: offset " << Offsets[i]
                   << " is outside the file\n";
      return true;
    }
    SourceLocation Start =
        Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
    SourceLocation End;
    if (i < Lengths.size()) {
      if (Offsets[i] + Lengths[i] > Code->getBufferSize()) {
        llvm::errs() << "error: invalid length " << Lengths[i]
                     << ", offset + length (" << Offsets[i] + Lengths[i]
                     << ") is outside the file.\n";
        return true;
      }
      End = Start.getLocWithOffset(Lengths[i]);
    } else {
      End = Sources.getLocForEndOfFile(ID);
    }
    Ranges.push_back(CharSourceRange::getCharRange(Start, End));
  }
  tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs()
        << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>"
                   << I->getReplacementText() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Replaces.size() == 0)
        return false; // Nothing changed, don't touch the file.

      std::string ErrorInfo;
      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                      llvm::raw_fd_ostream::F_Binary);
      if (!ErrorInfo.empty()) {
        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
        return true;
      }
      Rewrite.getEditBuffer(ID).write(FileStream);
      FileStream.flush();
    } else {
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemple #7
0
// Returns true on error.
static bool format(StringRef FileName) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
      MemoryBuffer::getFileOrSTDIN(FileName);
  if (std::error_code EC = CodeOrErr.getError()) {
    errs() << EC.message() << "\n";
    return true;
  }
  std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
  if (Code->getBufferSize() == 0)
    return false; // Empty files are formatted correctly.
  std::vector<tooling::Range> Ranges;
  if (fillRanges(Code.get(), Ranges))
    return true;
  StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName;
  FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle);
  if (SortIncludes.getNumOccurrences() != 0)
    FormatStyle.SortIncludes = SortIncludes;
  unsigned CursorPosition = Cursor;
  Replacements Replaces = sortIncludes(FormatStyle, Code->getBuffer(), Ranges,
                                       AssumedFileName, &CursorPosition);
  auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces);
  if (!ChangedCode) {
    llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n";
    return true;
  }
  for (const auto &R : Replaces)
    Ranges.push_back({R.getOffset(), R.getLength()});

  bool IncompleteFormat = false;
  Replacements FormatChanges = reformat(FormatStyle, *ChangedCode, Ranges,
                                        AssumedFileName, &IncompleteFormat);
  Replaces = tooling::mergeReplacements(Replaces, FormatChanges);
  if (OutputXML) {
    outs() << "<?xml version='1.0'?>\n<replacements "
              "xml:space='preserve' incomplete_format='"
           << (IncompleteFormat ? "true" : "false") << "'>\n";
    if (Cursor.getNumOccurrences() != 0)
      outs() << "<cursor>"
             << tooling::shiftedCodePosition(FormatChanges, CursorPosition)
             << "</cursor>\n";

    outputReplacementsXML(Replaces); 
    outs() << "</replacements>\n";
  } else {
    IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
        new vfs::InMemoryFileSystem);
    FileManager Files(FileSystemOptions(), InMemoryFileSystem);
    DiagnosticsEngine Diagnostics(
        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
        new DiagnosticOptions);
    SourceManager Sources(Diagnostics, Files);
    FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files,
                                   InMemoryFileSystem.get());
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (FileName == "-")
        errs() << "error: cannot use -i when reading from stdin.\n";
      else if (Rewrite.overwriteChangedFiles())
        return true;
    } else {
      if (Cursor.getNumOccurrences() != 0)
        outs() << "{ \"Cursor\": "
               << tooling::shiftedCodePosition(FormatChanges, CursorPosition)
               << ", \"IncompleteFormat\": "
               << (IncompleteFormat ? "true" : "false") << " }\n";
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
Exemple #8
0
static bool fillRanges(MemoryBuffer *Code,
                       std::vector<tooling::Range> &Ranges) {
  IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
      new vfs::InMemoryFileSystem);
  FileManager Files(FileSystemOptions(), InMemoryFileSystem);
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  FileID ID = createInMemoryFile("<irrelevant>", Code, Sources, Files,
                                 InMemoryFileSystem.get());
  if (!LineRanges.empty()) {
    if (!Offsets.empty() || !Lengths.empty()) {
      errs() << "error: cannot use -lines with -offset/-length\n";
      return true;
    }

    for (unsigned i = 0, e = LineRanges.size(); i < e; ++i) {
      unsigned FromLine, ToLine;
      if (parseLineRange(LineRanges[i], FromLine, ToLine)) {
        errs() << "error: invalid <start line>:<end line> pair\n";
        return true;
      }
      if (FromLine > ToLine) {
        errs() << "error: start line should be less than end line\n";
        return true;
      }
      SourceLocation Start = Sources.translateLineCol(ID, FromLine, 1);
      SourceLocation End = Sources.translateLineCol(ID, ToLine, UINT_MAX);
      if (Start.isInvalid() || End.isInvalid())
        return true;
      unsigned Offset = Sources.getFileOffset(Start);
      unsigned Length = Sources.getFileOffset(End) - Offset;
      Ranges.push_back(tooling::Range(Offset, Length));
    }
    return false;
  }

  if (Offsets.empty())
    Offsets.push_back(0);
  if (Offsets.size() != Lengths.size() &&
      !(Offsets.size() == 1 && Lengths.empty())) {
    errs() << "error: number of -offset and -length arguments must match.\n";
    return true;
  }
  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
    if (Offsets[i] >= Code->getBufferSize()) {
      errs() << "error: offset " << Offsets[i] << " is outside the file\n";
      return true;
    }
    SourceLocation Start =
        Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
    SourceLocation End;
    if (i < Lengths.size()) {
      if (Offsets[i] + Lengths[i] > Code->getBufferSize()) {
        errs() << "error: invalid length " << Lengths[i]
               << ", offset + length (" << Offsets[i] + Lengths[i]
               << ") is outside the file.\n";
        return true;
      }
      End = Start.getLocWithOffset(Lengths[i]);
    } else {
      End = Sources.getLocForEndOfFile(ID);
    }
    unsigned Offset = Sources.getFileOffset(Start);
    unsigned Length = Sources.getFileOffset(End) - Offset;
    Ranges.push_back(tooling::Range(Offset, Length));
  }
  return false;
}
Exemple #9
0
// Returns true on error.
static bool format(StringRef FileName) {
  if (!OutputXML && Inplace && FileName == "-") {
    errs() << "error: cannot use -i when reading from stdin.\n";
    return false;
  }
  // On Windows, overwriting a file with an open file mapping doesn't work,
  // so read the whole file into memory when formatting in-place.
  ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
      !OutputXML && Inplace ? MemoryBuffer::getFileAsStream(FileName) :
                              MemoryBuffer::getFileOrSTDIN(FileName);
  if (std::error_code EC = CodeOrErr.getError()) {
    errs() << EC.message() << "\n";
    return true;
  }
  std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
  if (Code->getBufferSize() == 0)
    return false; // Empty files are formatted correctly.
  std::vector<tooling::Range> Ranges;
  if (fillRanges(Code.get(), Ranges))
    return true;
  StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName;

  llvm::Expected<FormatStyle> FormatStyle =
      getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer());
  if (!FormatStyle) {
    llvm::errs() << llvm::toString(FormatStyle.takeError()) << "\n";
    return true;
  }

  if (SortIncludes.getNumOccurrences() != 0)
    FormatStyle->SortIncludes = SortIncludes;
  unsigned CursorPosition = Cursor;
  Replacements Replaces = sortIncludes(*FormatStyle, Code->getBuffer(), Ranges,
                                       AssumedFileName, &CursorPosition);
  auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces);
  if (!ChangedCode) {
    llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n";
    return true;
  }
  // Get new affected ranges after sorting `#includes`.
  Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
  FormattingAttemptStatus Status;
  Replacements FormatChanges = reformat(*FormatStyle, *ChangedCode, Ranges,
                                        AssumedFileName, &Status);
  Replaces = Replaces.merge(FormatChanges);
  if (OutputXML) {
    outs() << "<?xml version='1.0'?>\n<replacements "
              "xml:space='preserve' incomplete_format='"
           << (Status.FormatComplete ? "false" : "true") << "'";
    if (!Status.FormatComplete)
      outs() << " line='" << Status.Line << "'";
    outs() << ">\n";
    if (Cursor.getNumOccurrences() != 0)
      outs() << "<cursor>"
             << FormatChanges.getShiftedCodePosition(CursorPosition)
             << "</cursor>\n";

    outputReplacementsXML(Replaces);
    outs() << "</replacements>\n";
  } else {
    IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
        new vfs::InMemoryFileSystem);
    FileManager Files(FileSystemOptions(), InMemoryFileSystem);
    DiagnosticsEngine Diagnostics(
        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
        new DiagnosticOptions);
    SourceManager Sources(Diagnostics, Files);
    FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files,
                                   InMemoryFileSystem.get());
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Rewrite.overwriteChangedFiles())
        return true;
    } else {
      if (Cursor.getNumOccurrences() != 0) {
        outs() << "{ \"Cursor\": "
               << FormatChanges.getShiftedCodePosition(CursorPosition)
               << ", \"IncompleteFormat\": "
               << (Status.FormatComplete ? "false" : "true");
        if (!Status.FormatComplete)
          outs() << ", \"Line\": " << Status.Line;
        outs() << " }\n";
      }
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}