1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "EditTracker.h" 6 7 #include <assert.h> 8 #include <stdio.h> 9 #include "llvm/Support/Path.h" 10 #include "llvm/Support/raw_ostream.h" 11 12 namespace { 13 14 const char* GetTag(RenameCategory category) { 15 switch (category) { 16 case RenameCategory::kEnumValue: 17 return "enum"; 18 case RenameCategory::kField: 19 return "var"; 20 case RenameCategory::kFunction: 21 return "func"; 22 case RenameCategory::kUnresolved: 23 return "unresolved"; 24 case RenameCategory::kVariable: 25 return "var"; 26 } 27 } 28 29 } // namespace 30 31 EditTracker::EditTracker(RenameCategory category) : category_(category) {} 32 33 void EditTracker::Add(const clang::SourceManager& source_manager, 34 clang::SourceLocation location, 35 llvm::StringRef original_text, 36 llvm::StringRef new_text) { 37 llvm::StringRef filename; 38 for (int i = 0; i < 10; i++) { 39 filename = source_manager.getFilename(location); 40 if (!filename.empty() || !location.isMacroID()) 41 break; 42 // Otherwise, no filename and the SourceLocation is a macro ID. Look one 43 // level up the stack... 44 location = source_manager.getImmediateMacroCallerLoc(location); 45 } 46 assert(!filename.empty() && "Can't track edit with no filename!"); 47 auto result = tracked_edits_.try_emplace(original_text); 48 if (result.second) { 49 result.first->getValue().new_text = new_text; 50 } 51 result.first->getValue().filenames.try_emplace(filename); 52 } 53 54 void EditTracker::SerializeTo(llvm::raw_ostream& output) const { 55 const char* tag = GetTag(category_); 56 for (const auto& edit : tracked_edits_) { 57 for (const auto& filename : edit.getValue().filenames) { 58 output << filename.getKey() << ":" << tag << ":" << edit.getKey() << ":" 59 << edit.getValue().new_text << "\n"; 60 } 61 } 62 } 63