Introduce Rewriter::IncreaseIndentation() which increase indentations for the lines between the given source range.
To determine what the indentation should be, a SourceLocation 'parentIndent' parameter is used that should be at a source location with an indentation one degree lower than the given range. llvm-svn: 129628
This commit is contained in:
parent
5bea4c3859
commit
0e993c3249
|
@ -246,7 +246,17 @@ public:
|
|||
/// printer to generate the replacement code. This returns true if the input
|
||||
/// could not be rewritten, or false if successful.
|
||||
bool ReplaceStmt(Stmt *From, Stmt *To);
|
||||
|
||||
|
||||
/// \brief Increase indentation for the lines between the given source range.
|
||||
/// To determine what the indentation should be, 'parentIndent' is used
|
||||
/// that should be at a source location with an indentation one degree
|
||||
/// lower than the given range.
|
||||
bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent);
|
||||
bool IncreaseIndentation(SourceRange range, SourceLocation parentIndent) {
|
||||
return IncreaseIndentation(CharSourceRange::getTokenRange(range),
|
||||
parentIndent);
|
||||
}
|
||||
|
||||
/// ConvertToString converts statement 'From' to a string using the
|
||||
/// pretty printer.
|
||||
std::string ConvertToString(Stmt *From);
|
||||
|
|
|
@ -312,3 +312,86 @@ std::string Rewriter::ConvertToString(Stmt *From) {
|
|||
From->printPretty(S, 0, PrintingPolicy(*LangOpts));
|
||||
return SStr;
|
||||
}
|
||||
|
||||
bool Rewriter::IncreaseIndentation(CharSourceRange range,
|
||||
SourceLocation parentIndent) {
|
||||
using llvm::StringRef;
|
||||
|
||||
if (!isRewritable(range.getBegin())) return true;
|
||||
if (!isRewritable(range.getEnd())) return true;
|
||||
if (!isRewritable(parentIndent)) return true;
|
||||
|
||||
FileID StartFileID, EndFileID, parentFileID;
|
||||
unsigned StartOff, EndOff, parentOff;
|
||||
|
||||
StartOff = getLocationOffsetAndFileID(range.getBegin(), StartFileID);
|
||||
EndOff = getLocationOffsetAndFileID(range.getEnd(), EndFileID);
|
||||
parentOff = getLocationOffsetAndFileID(parentIndent, parentFileID);
|
||||
|
||||
if (StartFileID != EndFileID || StartFileID != parentFileID)
|
||||
return true;
|
||||
if (StartOff >= EndOff || parentOff >= StartOff)
|
||||
return true;
|
||||
|
||||
FileID FID = StartFileID;
|
||||
StringRef MB = SourceMgr->getBufferData(FID);
|
||||
|
||||
unsigned parentLineNo = SourceMgr->getLineNumber(FID, parentOff) - 1;
|
||||
unsigned startLineNo = SourceMgr->getLineNumber(FID, StartOff) - 1;
|
||||
unsigned endLineNo = SourceMgr->getLineNumber(FID, EndOff) - 1;
|
||||
|
||||
const SrcMgr::ContentCache *
|
||||
Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
|
||||
|
||||
// Find where the line starts for the three offsets.
|
||||
unsigned parentLineOffs = Content->SourceLineCache[parentLineNo];
|
||||
unsigned startLineOffs = Content->SourceLineCache[startLineNo];
|
||||
unsigned endLineOffs = Content->SourceLineCache[endLineNo];
|
||||
|
||||
if (startLineOffs == endLineOffs || startLineOffs == parentLineOffs)
|
||||
return true;
|
||||
|
||||
// Find the whitespace at the start of each line.
|
||||
StringRef parentSpace, startSpace, endSpace;
|
||||
{
|
||||
unsigned i = parentLineOffs;
|
||||
while (isWhitespace(MB[i]))
|
||||
++i;
|
||||
parentSpace = MB.substr(parentLineOffs, i-parentLineOffs);
|
||||
|
||||
i = startLineOffs;
|
||||
while (isWhitespace(MB[i]))
|
||||
++i;
|
||||
startSpace = MB.substr(startLineOffs, i-startLineOffs);
|
||||
|
||||
i = endLineOffs;
|
||||
while (isWhitespace(MB[i]))
|
||||
++i;
|
||||
endSpace = MB.substr(endLineOffs, i-endLineOffs);
|
||||
}
|
||||
if (parentSpace.size() >= startSpace.size())
|
||||
return true;
|
||||
if (!startSpace.startswith(parentSpace))
|
||||
return true;
|
||||
|
||||
llvm::StringRef indent = startSpace.substr(parentSpace.size());
|
||||
|
||||
// Indent the lines between start/end offsets.
|
||||
RewriteBuffer &RB = getEditBuffer(FID);
|
||||
for (unsigned i = startLineOffs; i != endLineOffs; ++i) {
|
||||
if (MB[i] == '\n') {
|
||||
unsigned startOfLine = i+1;
|
||||
if (startOfLine == endLineOffs)
|
||||
break;
|
||||
StringRef origIndent;
|
||||
unsigned ws = startOfLine;
|
||||
while (isWhitespace(MB[ws]))
|
||||
++ws;
|
||||
origIndent = MB.substr(startOfLine, ws-startOfLine);
|
||||
if (origIndent.startswith(startSpace))
|
||||
RB.InsertText(startOfLine, indent, /*InsertAfter=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue