コード例 #1
0
ファイル: swift-format.cpp プロジェクト: johnno1962b/swift
    // 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()) {
        llvm::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.

      FormatterDocument Doc(std::move(Code));

      if (!Offsets.empty() || !Lengths.empty()) {
        if (Offsets.size() != Lengths.size()) {
          llvm::errs() << "error: number of offsets not equal to number of lengths.\n";
          return true;
        }

        for ( unsigned i=0 ; i < Offsets.size() ; i++ ) {
          unsigned FromLine = Doc.getLineAndColumn(Offsets[i]).first;
          unsigned ToLine = Doc.getLineAndColumn(Offsets[i] + Lengths[i]).first;
          if (ToLine == 0) {
            llvm::errs() << "error: offset + length after end of file\n";
            return true;
          }
          std::ostringstream s;
          s << FromLine << ":" << ToLine;
          LineRanges.push_back(s.str());
        }
      }

      if (LineRanges.empty())
        LineRanges.push_back("1:999999");

      std::string Output = Doc.memBuffer().getBuffer();
      Replacements Replaces;

      for ( unsigned Range = 0 ; Range < LineRanges.size() ; Range++ ) {
        unsigned FromLine, ToLine;
        if (parseLineRange(LineRanges[Range], FromLine, ToLine)) {
          llvm::errs() << "error: invalid <start line>:<end line> pair\n";
          return true;
        }
        if (FromLine > ToLine) {
          llvm::errs() << "error: start line should be less than end line\n";
          return true;
        }

        for ( unsigned Line = FromLine ; Line<=ToLine ; Line++ ) {
          size_t Offset = getOffsetOfLine(Line,Output);
          ssize_t Length = getOffsetOfLine(Line+1,Output)-1-Offset;
          if (Length < 0)
            break;

          std::string Formatted = Doc.reformat(LineRange(Line,1), FormatOptions).second;
          if (Formatted.find_first_not_of(" \t\v\f", 0) == StringRef::npos)
              Formatted = "";

          if (Formatted == Output.substr(Offset, Length))
            continue;

          Output.replace(Offset, Length, Formatted);
          Doc.updateCode(std::move(MemoryBuffer::getMemBuffer(Output)));
          Replaces.insert(clang::tooling::Replacement(FileName, Offset, Length, Formatted));
        }
      }

      if (OutputXML) {
        llvm::outs() << "<?xml version='1.0'?>\n<replacements>\n";
        outputReplacementsXML(Replaces);
        llvm::outs() << "</replacements>\n";
      } else {
        if (Inplace) {
          if (FileName == "-") {
            llvm::errs() << "error: cannot use -i when reading from stdin.\n";
            return true;
          }
          else {
            std::error_code EC;
            raw_fd_ostream writer(FileName, EC, llvm::sys::fs::F_None);
            if (EC) {
              llvm::errs() << "error: writing " << FileName << ": " << EC.message() << "\n";
              return true;
            }
            writer << Output;
          }
        } else {
          llvm::outs() << Output;
        }
      }

      return false;
    }
コード例 #2
0
ファイル: ClangFormat.cpp プロジェクト: CSI-LLVM/clang
// 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;
}
コード例 #3
0
ファイル: ClangFormat.cpp プロジェクト: PolyJIT/clang
// 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;
}