formatAndApplyAllReplacements takes a set of Replacements, applies them on a
Rewriter, and reformats the changed code.
Details
- Reviewers
klimek djasper - Commits
- rG4c1ef97adb1e: Added formatAndApplyAllReplacements that works on multiple files in libTooling.
rC264745: Added formatAndApplyAllReplacements that works on multiple files in libTooling.
rL264745: Added formatAndApplyAllReplacements that works on multiple files in libTooling.
Diff Detail
- Repository
- rL LLVM
Event Timeline
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
237 ↗ | (On Diff #49740) | Hm... I am not sure here. I think I would implement this entirely without FileManager or FileEntries, just based on the names of the file. I guess you are worried about different paths leading to the same FileEntry? |
include/clang/Tooling/ReplacementsFormat.h | ||
1 ↗ | (On Diff #49740) | I think this can happily live in Refactoring.h/cpp for now. |
40 ↗ | (On Diff #49740) | This is probably a pre-existing issue in formatReplacements, but I think conceptually it might be wrong to hand in the Style. I think it might be a better idea to use clang::format::getStyle() with the filename stored inside of the replacement to get the style that should actually be used for any given change. Not sure whether we'd also want the capability to overwrite this. Manuel, what do you think? |
- Moved formatAndApplyAllReplacements to Tooling/Refactoing; added an overloaded version of formatAndApplyAllReplacements that takes no Style; groupReplacementsByFile groups Replacements by filename instead of FileEntry.
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
237 ↗ | (On Diff #49740) | You are right. Getting rid of FileManger would make more sense for users. And yes, I was worrying about different names leading to the same entry. Do we need to worry about this case? Or we can assume Replacements for the same file always have the same file path? |
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
228 ↗ | (On Diff #49807) | This was pre-existing, but I'd remove the "InFile" suffix. It doesn't seem to add any information. |
230 ↗ | (On Diff #49807) | I think the key type in a map is always const, so no need for "const". |
235 ↗ | (On Diff #49807) | I also wonder whether this should really return a map. I find such maps in interfaces sometimes a bit difficult as they have some cost and the subsequent analyses might actually prefer a different container. How about instead just returning a vector<Replacements>? I mean the Replacements themselves already have the filename stored in them so the key in the map is redundant anyway. Manuel, any thoughts? |
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
228 ↗ | (On Diff #49807) | Will remove the "InFile" suffix. |
230 ↗ | (On Diff #49807) | I think "const" is needed since the Entry passed to map's [] operator is of type const FileEntry * in FileToReplaces[Entry].push_back(Replace). The code didn't compile without the "const" qualifier. |
235 ↗ | (On Diff #49807) | But I think the tradeoff of using vector<Replacements> is the insertion time since we'd need to index Replcements with the same filename for each insertion. Or maybe we can have a map from filename to vector index as a local variable and return a vector<Replacements>? |
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
230 ↗ | (On Diff #49807) | Well, now it's a string and the strings are copied anyway. I am pretty sure it will compile after removing "const". |
235 ↗ | (On Diff #49807) | Yes, that is what I would probably do, have a local map and return a vector to keep the interface cleaner. But lets see what Manuel thinks. |
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
230 ↗ | (On Diff #49807) | Ooops! I was on another git branch! Yes, it definitely compiles for string. Sorry about that. |
Friendly PING.
@klimek
Hi Manuel, what do you think about the return type for
groupReplacementsByFile?
Daniel suggests that instead of "std::map<std::string, Replacements>", it
returns "std::vector<Replacements>".
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
237 ↗ | (On Diff #49740) | I like a map-based interface slightly better here, mainly because I think it's a bit harder to write buggy code against it, it's less work if the user wants to apply some kind of sharding (threads can just hand around the vectors without the need to loop over the vector yet again to split it, or hand indices around), and (to me at least) it is slightly easier to grasp the function's contract. Regarding the FileEntries, I'm not overly worried about file entries leading to the same file (I believe this is not too hard to handle one level higher if necessary), and the interface would seem significantly simpler without the FileManager. |
include/clang/Tooling/ReplacementsFormat.h | ||
40 ↗ | (On Diff #49740) | (not sure whether that's still unresolved, as I think I talked about this with Eric already) |
- renamed calculateChangedRangesInFile to calculateChangedRanges; removed const from FileToReplacementsMap key type.
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
231 ↗ | (On Diff #50627) | Honestly, I'd get rid of the typedef. Daniel, what do you think? |
lib/Tooling/Refactoring.cpp | ||
90 ↗ | (On Diff #50627) | Just call the above with the format::getStyle("file", FilePath, "LLVM")? |
unittests/Tooling/RefactoringTest.cpp | ||
206 ↗ | (On Diff #50627) | Also use a ColumnLimit to make the test more readable? |
include/clang/Tooling/Core/Replacement.h | ||
---|---|---|
231 ↗ | (On Diff #50627) | I agree. I don't think it carries its weight and actually makes the code harder to read. Plus all users can probably use auto :-). |
lib/Tooling/Refactoring.cpp | ||
---|---|---|
90 ↗ | (On Diff #50627) | Ah, right; In that case, we have 2 options:
|
- removed FileToReplacementsMap typedef; refactored formatAndApplyReplacements to reduce duplicated code.
lib/Tooling/Refactoring.cpp | ||
---|---|---|
90 ↗ | (On Diff #50627) | Adding a helper function seems to do the trick too. |
unittests/Tooling/RefactoringTest.cpp | ||
---|---|---|
206 ↗ | (On Diff #51166) | I'd rely on the general case to be covered by the other test then, and just test that the style is picked up correctly (or falls back correctly to LLVM style). |
unittests/Tooling/RefactoringTest.cpp | ||
---|---|---|
206 ↗ | (On Diff #51166) | You are right. Shall I remove this test case for now and add general test cases(I mean non-unit test) for format::getStyle in the future? |
Just wanted to check if there are existing test cases for format::getStyle.
If there is no test for it, I'll add test cases for sure :=)
include/clang/Tooling/Refactoring.h | ||
---|---|---|
91 ↗ | (On Diff #51433) | Do you have a use case where we'd want to call this with a fixed style? Otherwise, I'd just remove this function for now. |
93 ↗ | (On Diff #51433) | Don't copy the comment for the function. It is bound to go out of sync and makes users wonder what the actual differences are. Put this function first and replace "Instead of .." with "This function use the filename stored in the replacements to determine the appropriate style.". Then in the comment to the other just write: "/// Same as above but use fixed style \p Style." |
include/clang/Tooling/Refactoring.h | ||
---|---|---|
91 ↗ | (On Diff #51433) | If the .clang-format doesn't exist, it can only fall back to one default style, which is LLVM now. Shouldn't users have the flexibility to specify other styles if there is no .clang-format file? |
include/clang/Tooling/Refactoring.h | ||
---|---|---|
91 ↗ | (On Diff #51433) | I am not sure, but I usually like to keep interfaces small until we have actual use cases. It is very hard to foresee in what ways this can possibly be used. An alternative might be to hand in the style as a string which is similar to what clang-format takes on the command line. Then people can supply "file", "Google", ... and we can hand that to getStyle(). |
- Change the Style parameter of formatAndApplyReplacements from FormatStyle to be a Style name string.