brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · cc6ba7e Raw
108 lines · cpp
1//===- RewriteBuffer.h - Buffer rewriting interface -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/RewriteBuffer.h"10#include "llvm/Support/raw_ostream.h"11 12using namespace llvm;13 14raw_ostream &RewriteBuffer::write(raw_ostream &Stream) const {15  // Walk RewriteRope chunks efficiently using MoveToNextPiece() instead of the16  // character iterator.17  for (RopePieceBTreeIterator I = begin(), E = end(); I != E;18       I.MoveToNextPiece())19    Stream << I.piece();20  return Stream;21}22 23/// Return true if this character is non-new-line whitespace:24/// ' ', '\\t', '\\f', '\\v', '\\r'.25static inline bool isWhitespaceExceptNL(unsigned char c) {26  return c == ' ' || c == '\t' || c == '\f' || c == '\v' || c == '\r';27}28 29void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size,30                               bool removeLineIfEmpty) {31  // Nothing to remove, exit early.32  if (Size == 0)33    return;34 35  unsigned RealOffset = getMappedOffset(OrigOffset, true);36  assert(RealOffset + Size <= Buffer.size() && "Invalid location");37 38  // Remove the dead characters.39  Buffer.erase(RealOffset, Size);40 41  // Add a delta so that future changes are offset correctly.42  AddReplaceDelta(OrigOffset, -Size);43 44  if (removeLineIfEmpty) {45    // Find the line that the remove occurred and if it is completely empty46    // remove the line as well.47 48    iterator curLineStart = begin();49    unsigned curLineStartOffs = 0;50    iterator posI = begin();51    for (unsigned i = 0; i != RealOffset; ++i) {52      if (*posI == '\n') {53        curLineStart = posI;54        ++curLineStart;55        curLineStartOffs = i + 1;56      }57      ++posI;58    }59 60    unsigned lineSize = 0;61    posI = curLineStart;62    while (posI != end() && isWhitespaceExceptNL(*posI)) {63      ++posI;64      ++lineSize;65    }66    if (posI != end() && *posI == '\n') {67      Buffer.erase(curLineStartOffs, lineSize + 1 /* + '\n'*/);68      // FIXME: Here, the offset of the start of the line is supposed to be69      // expressed in terms of the original input not the "real" rewrite70      // buffer.  How do we compute that reliably?  It might be tempting to use71      // curLineStartOffs + OrigOffset - RealOffset, but that assumes the72      // difference between the original and real offset is the same at the73      // removed text and at the start of the line, but that's not true if74      // edits were previously made earlier on the line.  This bug is also75      // documented by a FIXME on the definition of76      // clang::Rewriter::RewriteOptions::RemoveLineIfEmpty.  A reproducer for77      // the implementation below is the test RemoveLineIfEmpty in78      // clang/unittests/Rewrite/RewriteBufferTest.cpp.79      AddReplaceDelta(curLineStartOffs, -(lineSize + 1 /* + '\n'*/));80    }81  }82}83 84void RewriteBuffer::InsertText(unsigned OrigOffset, StringRef Str,85                               bool InsertAfter) {86  // Nothing to insert, exit early.87  if (Str.empty())88    return;89 90  unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);91  Buffer.insert(RealOffset, Str.begin(), Str.end());92 93  // Add a delta so that future changes are offset correctly.94  AddInsertDelta(OrigOffset, Str.size());95}96 97/// ReplaceText - This method replaces a range of characters in the input98/// buffer with a new string.  This is effectively a combined "remove+insert"99/// operation.100void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,101                                StringRef NewStr) {102  unsigned RealOffset = getMappedOffset(OrigOffset, true);103  Buffer.erase(RealOffset, OrigLength);104  Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());105  if (OrigLength != NewStr.size())106    AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);107}108