// 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; }
// 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; }
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; }
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()); }
// 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; }
// 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; }
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; }
// 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; }